/// <summary> /// 执行结算 /// </summary> public override void Execute() { _context = new DataContext(); #region//检测订单有效性 if (null == _order) { _errorMessage = "订单数据不存在!"; return; } if (_order.BusinessType != (int)BusinessServiceType.Visiting) { _errorMessage = "当前订单不是有效的上门服务订单!"; return; } if (_order.Status != (int)VisitingServiceOrderStatus.WorkerServiceDone) { _errorMessage = "当前订单状态不适合进行结算处理!"; return; } #endregion #region //结算处理 #region //1、计算订单需要结算的金额 //线下支付,但下单时有预约金 if (_order.PaymentType == (int)BusinessServiceOrderPayment.OffLine) { if (_order.PrepaidAmount > 0) { _settlementAmount = _order.PrepaidAmount; } } else if (_order.PaiedTime.HasValue) { _settlementAmount = _order.ActualOrderAmount; } else { throw new Exception("当前订单数据异常(线上支付方式但未检测到付款信息),不能自动确定服务完成!"); } _settlementAmount = Math.Abs(_settlementAmount); #endregion //需要结算,先结算 if (_settlementAmount > 0) { #region//2、检测订单付款方 //支付方 BusinessServicePayer payer = default(BusinessServicePayer); //业务信息 var business = _context.KylinService_Business.SingleOrDefault(p => p.BusinessID == _order.BusinessID); payer = (BusinessServicePayer)Enum.Parse(typeof(BusinessServicePayer), business.PayerType.ToString()); #endregion #region//3、获取用户资金并检测 _user = _context.User_Account.SingleOrDefault(p => p.UserID == _order.UserID); if (null == _user) { _errorMessage = "用户数据异常,未检测到用户信息!"; return; } _context.User_Account.Attach(_user); _context.Entry(_user).Property(p => p.Balance).IsModified = true; #endregion #region //4、检测并获取服务提供方信息 //服务提供方类型 BusinessOrderServiceProvider servicerProvider = default(BusinessOrderServiceProvider); servicerProvider = (BusinessOrderServiceProvider)Enum.Parse(typeof(BusinessOrderServiceProvider), _order.ServerType.ToString()); switch (servicerProvider) { case BusinessOrderServiceProvider.Merchant: _merchant = _context.Merchant_Account.SingleOrDefault(p => p.MerchantID == _order.MerchantID); break; case BusinessOrderServiceProvider.Person: _worker = _context.User_Account.SingleOrDefault(p => p.UserID == _order.WorkerID); break; } //如果服务者不存在,则返回错误 if (_merchant == null && _worker == null) { _errorMessage = "启奏陛下,订单的服务提供者最近学会一种新的奇门循土术,突然就不见了,请陛下明察!"; return; } if (_merchant != null) { _context.Merchant_Account.Attach(_merchant); _context.Entry(_merchant).Property(p => p.Balance).IsModified = true; _context.Entry(_merchant).Property(p => p.FreezeMoney).IsModified = true; } if (_worker != null) { _context.User_Account.Attach(_worker); _context.Entry(_worker).Property(p => p.Balance).IsModified = true; _context.Entry(_worker).Property(p => p.FreezeMoney).IsModified = true; } #endregion #region //5、获取当前订单所归属区域的运营商 //区域(大区域,即运营商区域) var operatorQuery = from op in _context.Area_Operator join ao in _context.Area_OperatorRelation on op.OperatorID equals ao.OperatorID where ao.AreaID == _order.AreaID select op; _operator = operatorQuery.FirstOrDefault(); if (null == _operator) { _errorMessage = "启奏陛下,订单所在区域运营商不存在,微臣不敢擅作主张,还请陛下圣断!"; return; } _context.Area_Operator.Attach(_operator); _context.Entry(_operator).Property(p => p.Balance).IsModified = true; //运营商基本资料 _operatorProfile = _context.Area_OperatorProfile.SingleOrDefault(p => p.OperatorID == _operator.OperatorID); #endregion #region //6、处理结算及记录 //6.1 如果付款方为服务者(商),表示服务人员付款给用户,则不需要考虑抽成 if (payer == BusinessServicePayer.Servicer) { //商户接单,商家付 if (servicerProvider == BusinessOrderServiceProvider.Merchant) { MerchantPaymentToUser(); } //个人服务者接单,个人服务者付 else if (servicerProvider == BusinessOrderServiceProvider.Person) { WorkerPaymentToUser(); } } //6.2 如果付款方为用户,表示用户付款给服务提供者,则从服务者(商)抽成 else if (payer == BusinessServicePayer.Custom) { //商户接单,付给商家 if (servicerProvider == BusinessOrderServiceProvider.Merchant) { UserPaymentToMerchant(); } //个人服务者接单,付给个人服务人员 else if (servicerProvider == BusinessOrderServiceProvider.Person) { UserPaymentToWorker(); } } else { _errorMessage = "妈呀,即不是服务受用方也不是服务提供方买单,莫非有雷锋慈善家赞助?先不处理了,陛下,你决定吧!"; return; } #endregion } if (Success) { #region//7、更新订单状态 if (_needProcessOrder) { _context.KylinService_Order.Attach(_order); _context.Entry(_order).Property(p => p.Status).IsModified = true; _context.Entry(_order).Property(p => p.ReceivedTime).IsModified = true; //修改订单状态为已完成 _order.Status = (int)VisitingServiceOrderStatus.UserServiceConfirmDone; _order.ReceivedTime = DateTime.Now; } #endregion #region//8、用户积分奖励 var pointCalc = new PointCalculator(_order.UserID, UserActivityType.OrderFinish); if (pointCalc.CanContinue) { int points = pointCalc.Score; //更新用户积分 _context.Entry(_user).Property(p => p.Points).IsModified = true; _user.Points += points; //积分获取记录 _context.User_PointsRecords.Add(new User_PointsRecords { ActivityType = (int)UserActivityType.OrderFinish, CreateTime = DateTime.Now, RecordsID = IDCreater.Instance.GetID(), Remark = string.Format("上门订单(编号:{0})交易完成,获得{1}积分。", _order.OrderCode, points), Score = points, UserID = _order.UserID }); } #endregion #region//9、用户经验值奖励 var empiricalCalc = new EmpiricalCalculator(_order.UserID, UserActivityType.OrderFinish); if (empiricalCalc.CanContinue) { int empirical = empiricalCalc.Score; //更新用户经验值 _context.Entry(_user).Property(p => p.Empirical).IsModified = true; _user.Empirical += empirical; //经验值获取记录 _context.User_EmpiricalRecords.Add(new User_EmpiricalRecords { ActivityType = (int)UserActivityType.OrderFinish, CreateTime = DateTime.Now, RecordsID = IDCreater.Instance.GetID(), Remark = string.Format("上门订单(编号:{0})交易完成,获得{1}点经验值。", _order.OrderCode, empirical), Score = empirical, UserID = _order.UserID }); } #endregion //返回处理结果 if (_context.SaveChanges() < 1) { _errorMessage = "操作失败!"; return; } else { _errorMessage = null; #region//10、消息推送 try { var pushRedis = Startup.PushRedisConfigs[RedisPushType.AppointOrderReceivedGoods]; if (null != pushRedis) { var msgContent = new AppointOrderReceivedGoodsContent { ActualOrderAmount = _order.ActualOrderAmount, OrderCode = _order.OrderCode, OrderID = _order.OrderID, UserFinishTime = _order.UserFinishTime ?? DateTime.Now, UserID = _order.UserID, UserName = _user.Username, MerchantID = _order.MerchantID, BusinessType = _order.BusinessType, ServerType = _order.ServerType, WorkerID = _order.WorkerID }; var pushDb = PushRedisContext.Redis.GetDatabase(pushRedis.DbIndex); if (pushDb != null) { pushDb.ListRightPush(pushRedis.Key, msgContent); } } } catch { } #endregion } } #endregion _context.Dispose(); }
/// <summary> /// 执行结算 /// </summary> public override void Execute() { #region//检测订单有效性 if (null == _order) { _errorMessage = "订单数据不存在!"; return; } if (_order.OrderStatus != (int)MerchantOrderStatus.WaitingReceipt) { _errorMessage = "当前订单状态不适合进行结算处理!"; return; } #endregion #region //结算处理 using (var db = new DataContext()) { #region//1、获取用户资金并检测 var user = db.User_Account.SingleOrDefault(p => p.UserID == _order.UserID); if (null == user) { _errorMessage = "用户数据异常,未检测到用户信息!"; return; } if (user.FreezeMoney < _order.ActualOrderAmount) { _errorMessage = "呼叫程序猿,用户钱跑哪去了?冻结资金结算不了当前订单!"; return; } #endregion #region//2、获得商家信息 var merchant = db.Merchant_Account.SingleOrDefault(p => p.MerchantID == _order.MerchantID); if (null == merchant) { _errorMessage = "哇哦,商家呢?跑哪去了,不见了?钱给谁?给谁?给谁……"; return; } #endregion #region//3、得到区域运营商信息 //区域(大区域,即运营商区域) var areaID = merchant.AreaID; var openAreas = CacheCollection.OpenAreaCache.Value(); var areaLayers = merchant.AreaLayer.Split(new[] { ',', '|' }, StringSplitOptions.RemoveEmptyEntries); foreach (var area in openAreas) { if (areaLayers.Contains(area.AreaID.ToString())) { areaID = area.AreaID; break; } } var operatorQuery = from op in db.Area_Operator join ao in db.Area_OperatorRelation on op.OperatorID equals ao.OperatorID where ao.AreaID == areaID select op; var operater = operatorQuery.FirstOrDefault(); if (null == operater) { _errorMessage = "启奏陛下,订单所在区域运营商不存在,微臣不敢擅作主张,还请陛下圣断!"; return; } //运营商基本资料 var operatorProfile = db.Area_OperatorProfile.SingleOrDefault(p => p.OperatorID == operater.OperatorID); #endregion #region//4、用户货款从冻结金额中结算并写入交易记录、资金明细 db.User_Account.Attach(user); db.Entry(user).Property(p => p.FreezeMoney).IsModified = true; user.FreezeMoney -= _order.ActualOrderAmount; #endregion #region//5、获取用户支付时的交易记录信息(从中获取平台交易流水号) var userTradeRecord = db.User_TradeRecords.Where(p => p.DataID == _order.OrderID).FirstOrDefault(); string mainTransCode = null != userTradeRecord ? userTradeRecord.PlatformTransactionCode : string.Empty; if (!string.IsNullOrWhiteSpace(mainTransCode) && mainTransCode.Length == 24) { mainTransCode = mainTransCode.Remove(23, 1); } if (mainTransCode.Length != 23) { mainTransCode = IDCreater.Instance.GetPlatformTransactionCode(PlatformTransactionType.BuyProduct, areaID); } //业务序号 int transIndex = 0; #endregion #region//6、货款结算给商家 string merchantGetSaleTransCode = mainTransCode + (++transIndex); db.Merchant_Account.Attach(merchant); db.Entry(merchant).Property(p => p.Balance).IsModified = true; merchant.Balance = merchant.Balance + _order.ActualOrderAmount; //写入商家交易记录 var merchantSaleTrandsRecords = new Merchant_TradeRecords { Amount = _order.ActualOrderAmount, CounterpartyId = _order.UserID, CounterpartyIdentity = (int)CounterpartyIdentity.User, CreateTime = DateTime.Now, DataID = _order.OrderID, LastBalance = merchant.Balance, MerchantID = merchant.MerchantID, PaymentType = (int)OnlinePaymentType.Balance, PlatformTransactionCode = merchantGetSaleTransCode, TradeID = IDCreater.Instance.GetID(), TradeInfo = string.Format("销售商品,订单编号:{0}", _order.OrderCode), TradeNo = string.Empty, TradeType = (int)MerchantTransType.ProductSales }; db.Merchant_TradeRecords.Add(merchantSaleTrandsRecords); //写入平台资金流水 db.Platform_MoneyTransaction.Add(new Platform_MoneyTransaction { Amount = merchantSaleTrandsRecords.Amount, AreaID = areaID, CustomAccountID = merchantSaleTrandsRecords.MerchantID, CustomIdentity = (int)CounterpartyIdentity.Merchant, CustomName = merchant.Name, IsMainTransaction = false, LastBalance = merchantSaleTrandsRecords.LastBalance, Remark = string.Format("销售商品,订单编号:{0}", _order.OrderCode), ThirdTransactionCode = string.Empty, TransactionCode = merchantGetSaleTransCode, TransactionTime = DateTime.Now, TransactionType = (int)PlatformTransactionType.SaleProduct }); #endregion //总抽成 decimal totalCommissionMoney = new AreaForMerchantCommissionCalculator(areaID, _order.MerchantID, AreaMerchantCommissionOption.MerchantProductOrder, _order.ActualOrderAmount).CommissionMoney; //抽成金额>0时 if (totalCommissionMoney > 0) { #region //7、区域运营商抽成 #region //商家返佣给运营商 merchant.Balance -= totalCommissionMoney; string merchantReturnTransCode = mainTransCode + (++transIndex); //写入商家返佣记录 var merchantReturnTrandsRecords = new Merchant_TradeRecords { Amount = -totalCommissionMoney, CounterpartyId = operater.OperatorID, CounterpartyIdentity = (int)CounterpartyIdentity.AreaOperator, CreateTime = DateTime.Now, DataID = _order.OrderID, LastBalance = merchant.Balance, MerchantID = _order.MerchantID, PaymentType = (int)OnlinePaymentType.Balance, PlatformTransactionCode = merchantReturnTransCode, TradeID = IDCreater.Instance.GetID(), TradeInfo = string.Format("销售商品返佣金给运营商,订单编号:{0}", _order.OrderCode), TradeNo = string.Empty, TradeType = (int)MerchantTransType.ReturnCommissionToOperator }; db.Merchant_TradeRecords.Add(merchantReturnTrandsRecords); //写入平台资金流水 db.Platform_MoneyTransaction.Add(new Platform_MoneyTransaction { Amount = merchantReturnTrandsRecords.Amount, AreaID = areaID, CustomAccountID = merchantReturnTrandsRecords.MerchantID, CustomIdentity = (int)CounterpartyIdentity.Merchant, CustomName = merchant.Name, IsMainTransaction = false, LastBalance = merchantReturnTrandsRecords.LastBalance, Remark = string.Format("销售商品返佣金给运营商,订单编号:{0}", _order.OrderCode), ThirdTransactionCode = string.Empty, TransactionCode = merchantReturnTransCode, TransactionTime = DateTime.Now, TransactionType = (int)PlatformTransactionType.PayCommission }); #endregion #region//运营商接收商家返佣 db.Area_Operator.Attach(operater); db.Entry(operater).Property(p => p.Balance).IsModified = true; operater.Balance += totalCommissionMoney; string operatorGetReturnCommissionTransCode = mainTransCode + (++transIndex); //写入运营商交易记录 var operatorGetReturnCommissionTrandsRecords = new AreaOperator_TradeRecords { Amount = totalCommissionMoney, CounterpartyId = _order.MerchantID, CounterpartyIdentity = (int)CounterpartyIdentity.Merchant, CreateTime = DateTime.Now, DataID = _order.OrderID, LastBalance = operater.Balance, OpeartorID = operater.OperatorID, PaymentType = (int)OnlinePaymentType.Balance, PlatformTransactionCode = operatorGetReturnCommissionTransCode, TradeID = IDCreater.Instance.GetID(), TradeInfo = string.Format("从商家销售商品中抽成,订单编号:{0}", _order.OrderCode), TradeNo = string.Empty, TradeType = (int)OperatorTradeType.CommissionGet }; db.AreaOperator_TradeRecords.Add(operatorGetReturnCommissionTrandsRecords); //写入平台资金流水 db.Platform_MoneyTransaction.Add(new Platform_MoneyTransaction { Amount = operatorGetReturnCommissionTrandsRecords.Amount, AreaID = areaID, CustomAccountID = operatorGetReturnCommissionTrandsRecords.OpeartorID, CustomIdentity = (int)CounterpartyIdentity.AreaOperator, CustomName = operatorProfile?.CompanyName, IsMainTransaction = false, LastBalance = operatorGetReturnCommissionTrandsRecords.LastBalance, Remark = string.Format("从商家销售商品中抽成,订单编号:{0}", _order.OrderCode), ThirdTransactionCode = string.Empty, TransactionCode = operatorGetReturnCommissionTransCode, TransactionTime = DateTime.Now, TransactionType = (int)PlatformTransactionType.CommissionGet }); #endregion #endregion #region//8、运营商返佣金给平台(平台抽成) //平台应抽成金额 decimal platformCommissionMoney = new PlatformCommissionCalculator(areaID, PlatformCommissionOption.AreaCommissionByMerchantOrder, totalCommissionMoney).CommissionMoney; //需要抽佣时(抽佣金额>0)才进入 if (platformCommissionMoney > 0) { //从余额中支付佣金给平台 operater.Balance = operater.Balance - platformCommissionMoney; //本次流水号 string operatorPayCommissionTransCode = mainTransCode + (++transIndex); //记录本次操作,写入运营商交易记录 var operatorPayCommissionTrandsRecords = new AreaOperator_TradeRecords { Amount = -platformCommissionMoney, CounterpartyId = 0, CounterpartyIdentity = (int)CounterpartyIdentity.Platform, CreateTime = DateTime.Now, DataID = _order.OrderID, LastBalance = operater.Balance, OpeartorID = operater.OperatorID, PaymentType = (int)OnlinePaymentType.Balance, PlatformTransactionCode = operatorPayCommissionTransCode, TradeID = IDCreater.Instance.GetID(), TradeInfo = string.Format("从商家订单抽成后返佣金给平台,订单编号:{0}", _order.OrderCode), TradeNo = string.Empty, TradeType = (int)OperatorTradeType.PayCommission }; db.AreaOperator_TradeRecords.Add(operatorPayCommissionTrandsRecords); //写入平台资金流水 db.Platform_MoneyTransaction.Add(new Platform_MoneyTransaction { Amount = operatorPayCommissionTrandsRecords.Amount, AreaID = areaID, CustomAccountID = operater.OperatorID, CustomIdentity = (int)CounterpartyIdentity.AreaOperator, CustomName = operatorProfile?.CompanyName, IsMainTransaction = false, LastBalance = operatorPayCommissionTrandsRecords.LastBalance, Remark = string.Format("从商家订单抽成后返佣金给平台,订单编号:{0}", _order.OrderCode), ThirdTransactionCode = string.Empty, TransactionCode = operatorPayCommissionTransCode, TransactionTime = DateTime.Now, TransactionType = (int)PlatformTransactionType.PayCommission }); } #endregion } #region//9、更新订单状态 if (_needProcessOrder) { db.Merchant_Order.Attach(_order); db.Entry(_order).Property(p => p.OrderStatus).IsModified = true; db.Entry(_order).Property(p => p.ReceivedTime).IsModified = true; //修改订单状态为已完成 _order.OrderStatus = (int)MerchantOrderStatus.Done; _order.ReceivedTime = DateTime.Now; } #endregion #region//10、用户积分奖励 var pointCalc = new PointCalculator(_order.UserID, UserActivityType.OrderFinish); if (pointCalc.CanContinue) { int points = pointCalc.Score; //更新用户积分 db.Entry(user).Property(p => p.Points).IsModified = true; user.Points += points; //积分获取记录 db.User_PointsRecords.Add(new User_PointsRecords { ActivityType = (int)UserActivityType.OrderFinish, CreateTime = DateTime.Now, RecordsID = IDCreater.Instance.GetID(), Remark = string.Format("订单(编号:{0})交易完成,获得{1}积分。", _order.OrderCode, points), Score = points, UserID = _order.UserID }); } #endregion #region//11、用户经验值奖励 var empiricalCalc = new EmpiricalCalculator(_order.UserID, UserActivityType.OrderFinish); if (empiricalCalc.CanContinue) { int empirical = empiricalCalc.Score; //更新用户经验值 db.Entry(user).Property(p => p.Empirical).IsModified = true; user.Empirical += empirical; //经验值获取记录 db.User_EmpiricalRecords.Add(new User_EmpiricalRecords { ActivityType = (int)UserActivityType.OrderFinish, CreateTime = DateTime.Now, RecordsID = IDCreater.Instance.GetID(), Remark = string.Format("订单(编号:{0})交易完成,获得{1}点经验值。", _order.OrderCode, empirical), Score = empirical, UserID = _order.UserID }); } #endregion //返回处理结果 if (db.SaveChanges() < 1) { _errorMessage = "操作失败!"; return; } else { _errorMessage = null; #region//12、消息推送 try { var pushRedis = Startup.PushRedisConfigs[RedisPushType.MerchantOrderReceivedGoods]; if (null != pushRedis) { var msgContent = new MerchantOrderReceivedGoodsContent { ActualOrderAmount = _order.ActualOrderAmount, OrderCode = _order.OrderCode, OrderID = _order.OrderID, ReceivedTime = _order.ReceivedTime ?? DateTime.Now, UserID = _order.UserID, UserName = user.Username, MerchantID = _order.MerchantID }; var pushDb = PushRedisContext.Redis.GetDatabase(pushRedis.DbIndex); if (pushDb != null) { pushDb.ListRightPush(pushRedis.Key, msgContent); } } } catch { } #endregion } } #endregion }