/// <summary> /// 获取商品的成本价 /// </summary> /// <param name="requestSysNo"></param> /// <returns></returns> private Dictionary <int, decimal> GetSOItemsCost(int requestSysNo) { Dictionary <int, decimal> result = new Dictionary <int, decimal>(); RMARequestInfo request = LoadWithRegistersBySysNo(requestSysNo); if (request != null) { var soItems = ExternalDomainBroker.GetSOItemList(request.SOSysNo.Value); request.Registers.ForEach(p => { var item = soItems.FirstOrDefault(q => q.ProductSysNo == p.BasicInfo.ProductSysNo); if (item != null && !result.Keys.Contains(p.BasicInfo.ProductSysNo.Value)) { result.Add(p.BasicInfo.ProductSysNo.Value, item.CostPrice ?? 0); } }); } return(result); }
/// <summary> /// 退款 /// </summary> /// <param name="entity"></param> public virtual void Refund(RefundBalanceInfo entity) { RefundBalanceInfo refundBalanceInfo; SOInfo soInfo; VerifyForRefund(entity, out soInfo, out refundBalanceInfo); soInfo.BaseInfo.GiftCardPay = soInfo.BaseInfo.GiftCardPay ?? 0M; refundBalanceInfo.GiftCardAmt = refundBalanceInfo.GiftCardAmt ?? 0M; refundBalanceInfo.PointAmt = refundBalanceInfo.PointAmt ?? 0; decimal availShipPrice, cashRemoveGiftCard, availGiftCard, totalRoBoBalanceAmt; int availPointAmt; CalculateAvailRefundAmt(entity, soInfo.BaseInfo, out availShipPrice, out cashRemoveGiftCard, out availGiftCard, out availPointAmt, out totalRoBoBalanceAmt); if (refundBalanceInfo.CashAmt > cashRemoveGiftCard || refundBalanceInfo.GiftCardAmt > availGiftCard || refundBalanceInfo.PointAmt > availPointAmt) { throw new BizException( ResouceManager.GetMessageString("RMA.RefundBalance", "Refund_ReCreateRefundBalance")); } decimal ROAmt; PreCheckForRefund(refundBalanceInfo, totalRoBoBalanceAmt, availShipPrice, out ROAmt); int tmpNewOrderSysNo = 0; #region 事务中执行退款操作 TransactionOptions options = new TransactionOptions(); options.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted; options.Timeout = TransactionManager.DefaultTimeout; using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, options)) { AbandonPoint(refundBalanceInfo); if (refundBalanceInfo.RefundPayType == RefundPayType.PrepayRefund) { if (refundBalanceInfo.CashAmt.Value > soInfo.BaseInfo.SOAmount) { throw new BizException(ResouceManager.GetMessageString("RMA.RefundBalance", "Refund_CashAmtValid")); } RefundPrepay(refundBalanceInfo); } else if (refundBalanceInfo.RefundPayType == RefundPayType.TransferPointRefund) { if (refundBalanceInfo.CashAmt.Value > soInfo.BaseInfo.SOAmount) { throw new BizException(ResouceManager.GetMessageString("RMA.RefundBalance", "Refund_CashAmtValid")); } TransferPointRefund(refundBalanceInfo); } CreateSOIncome(refundBalanceInfo); // 现金部分生成新礼品卡 RefundInfo refundInfo = refundProcessor.LoadBySysNo(entity.OriginalRefundSysNo.Value); if (refundBalanceInfo.RefundPayType == RefundPayType.GiftCardRefund && refundBalanceInfo.CashAmt > 0) { refundProcessor.CreateElectronicGiftCard(refundInfo, refundBalanceInfo.CashAmt.Value, "ROBalance"); } //礼品卡部分依次退返 if (refundBalanceInfo.GiftCardAmt > 0) { refundProcessor.RefundGiftCard(refundInfo, refundBalanceInfo.GiftCardAmt.Value, "ROBalance", refundBalanceInfo.SysNo.Value); } UpdateRefundBalanceForRefund(entity.SysNo.Value, ROAmt, out tmpNewOrderSysNo); //20130808 Chester Added:完成RMA退款调整单待审核- 待办事项: EventPublisher.Publish <RMACompleteRefundBalanceWaitingForAuditMessage>(new RMACompleteRefundBalanceWaitingForAuditMessage() { RefundBalanceSysNo = entity.SysNo.Value, RefundSysNo = entity.OriginalRefundSysNo.Value, CurrentUserSysNo = ServiceContext.Current.UserSysNo }); scope.Complete(); } #endregion //发送SSB string stockID = ExternalDomainBroker.GetSOItemList(soInfo.SysNo.Value).FirstOrDefault().StockSysNo.Value.ToString(); if (stockID != null && soInfo != null) { //if (stockID.Trim() == RMAConst.WarehouseNo_GZ // || stockID.Trim() == RMAConst.WarehouseNo_XA // || soInfo.InvoiceInfo.IsVAT == true) if (soInfo.InvoiceInfo.IsVAT == true) { ObjectFactory <SendSSBProcessor> .Instance.SendADJUSTMessage(tmpNewOrderSysNo, stockID, entity.CompanyCode); } } }
/// <summary> /// 计算可退款金额(运费,现金,礼品卡,积分) /// </summary> /// <param name="entity"></param> /// <param name="soBaseInfo"></param> /// <param name="availShipPrice">可退运费</param> /// <param name="cashRemoveGiftCard">可退现金</param> /// <param name="availGiftCard">可退礼品卡</param> /// <param name="availPointAmt">可退积分</param> /// <param name="totalRoBoBalanceAmt">历史退款总额</param> private void CalculateAvailRefundAmt(RefundBalanceInfo entity, SOBaseInfo soBaseInfo, out decimal availShipPrice, out decimal cashRemoveGiftCard, out decimal availGiftCard, out int availPointAmt, out decimal totalRoBoBalanceAmt) { string stockID = ExternalDomainBroker.GetSOItemList(soBaseInfo.SysNo.Value).FirstOrDefault().StockSysNo.Value.ToString(); #region 历史退款 //正常商品退款总额 HistoryRefundAmount historyAmt = refundProcessor.GetHistoryRefundAmt(entity.OriginalSOSysNo.Value, entity.ProductSysNo.Value, stockID); decimal totalGiftAmtHistory = historyAmt.TotalGiftCardAmt; int totalPointAmtHistory = historyAmt.TotalPointAmt; totalRoBoBalanceAmt = historyAmt.TotalRoBalanceAmt; historyAmt = refundProcessor.GetHistoryRefundAmt(entity.OriginalSOSysNo.Value, 0, stockID); decimal totalCashAmtHistory = historyAmt.TotalCashAmt; //运费补偿退款总额 decimal totalShipPriceAmtHistory = historyAmt.TotalShipPriceAmt; #endregion 历史退款 #region 计算可退现金/积分/礼品卡 //运费总额(运费+保价费+附加费) decimal shipPrice = GetShipFee(soBaseInfo.SysNo.Value, stockID); //可退运费(运费总额-已退运费总额) availShipPrice = shipPrice - totalShipPriceAmtHistory; if (availShipPrice < 0) { availShipPrice = 0; } //可退现金 cashRemoveGiftCard = soBaseInfo.CashPay + shipPrice + soBaseInfo.PromotionAmount.Value - soBaseInfo.GiftCardPay.Value - totalCashAmtHistory; if (soBaseInfo.GiftCardPay == 0 && availShipPrice > 0 && entity.ProductSysNo != 0) { cashRemoveGiftCard -= availShipPrice; } if (cashRemoveGiftCard < 0) { cashRemoveGiftCard = 0; } ///可退礼品卡金额 availGiftCard = soBaseInfo.GiftCardPay.Value - totalGiftAmtHistory; if (soBaseInfo.GiftCardPay.Value > 0 && availShipPrice > 0 && entity.ProductSysNo != 0) { availGiftCard -= availShipPrice; } if (availGiftCard < 0) { availGiftCard = 0; } //可退积分 availPointAmt = soBaseInfo.PointPay.Value - totalPointAmtHistory; if (availPointAmt < 0) { availPointAmt = 0; } #endregion 计算可退现金/积分/礼品卡 }
/// <summary> /// 计算退现金、初算退礼品卡、退现金、退礼品卡 /// </summary> /// <param name="entity"></param> /// <param name="soBaseInfo"></param> private void Calc(RefundBalanceInfo entity, SOBaseInfo soBaseInfo) { decimal availShipPrice, cashRemoveGiftCard, availGiftCard, totalRoBoBalanceAmt; int availPointAmt; CalculateAvailRefundAmt(entity, soBaseInfo, out availShipPrice, out cashRemoveGiftCard, out availGiftCard, out availPointAmt, out totalRoBoBalanceAmt); soBaseInfo.GiftCardPay = soBaseInfo.GiftCardPay ?? 0M; #region 根据可用退现金,修正调整单金额的现金、礼品卡、积分部分 if (entity.CashAmt > 0) { if (cashRemoveGiftCard >= entity.CashAmt)//有现金可作调整单 { entity.GiftCardAmt = 0; entity.PointAmt = 0; } else if (cashRemoveGiftCard == 0)//可退现金为0 { if (availGiftCard > 0) { if (entity.CashAmt <= availGiftCard)//礼品卡可用 { entity.GiftCardAmt = entity.CashAmt; entity.PointAmt = 0; } else//退完礼品卡还有金额转为积分 { entity.GiftCardAmt = availGiftCard; entity.PointAmt = Convert.ToInt32(Decimal.Round((entity.CashAmt.Value - availGiftCard) * pointExchangeRate, 0)); if (entity.PointAmt > availPointAmt) { entity.PointAmt = availPointAmt; } if (availGiftCard == 0 && availPointAmt == 0) { throw new BizException(ResouceManager.GetMessageString("RMA.RefundBalance", "RefundTooMuch")); } if (availGiftCard == 0 && entity.CashAmt.Value < 0.1m) { throw new BizException(ResouceManager.GetMessageString("RMA.RefundBalance", "OnlyAdjustPoints")); } } } else { entity.PointAmt = Convert.ToInt32(Decimal.Round(entity.CashAmt.Value * pointExchangeRate, 0)); } entity.CashAmt = 0; } else//有部分现金可退,剩余部分使用礼品卡 { entity.GiftCardAmt = entity.CashAmt - cashRemoveGiftCard; if (entity.GiftCardAmt > availGiftCard) { entity.PointAmt = Convert.ToInt32(Decimal.Round((entity.GiftCardAmt.Value - availGiftCard) * pointExchangeRate, 0)); if (entity.PointAmt > availPointAmt) { entity.PointAmt = availPointAmt; } entity.GiftCardAmt = availGiftCard; } else { entity.PointAmt = 0; } entity.CashAmt = cashRemoveGiftCard; } } else { entity.GiftCardAmt = 0; entity.PointAmt = 0; } #endregion 根据可用退现金,修正调整单金额的现金、礼品卡、积分部分 if (entity.ProductSysNo != 0) //商品调整 { #region SOItem RefundItemInfo refundItem = refundBalanceDA.GetRefundTotalAmount(entity); decimal tempRefunded = (refundItem.RefundPrice ?? 0M) + entity.CashAmt.Value + totalRoBoBalanceAmt; decimal productValue = refundItem.ProductValue ?? 0; if (productValue < tempRefunded) { throw new BizException(ResouceManager.GetMessageString("RMA.RefundBalance", "RefundTooMuch")); } if (tempRefunded < 0) { throw new BizException(ResouceManager.GetMessageString("RMA.RefundBalance", "NotGreaterThanRefundedAmt")); } #region 现金、礼品卡、积分金额划分 decimal refundAmt = entity.CashAmt.Value + entity.GiftCardAmt.Value; if (refundAmt > 0 && entity.PointAmt == 0) { #region 计算 现金与积分比率 decimal originalSOCashPointRate = 0; //不四舍五入的比率:现金部分与总额的比例 decimal pointOnly = 0; // 仅积分支付部分对应的价值 decimal cashOnly = 0; // 仅现金支付部分对应的价值 decimal totalPromotionDiscount = 0; //优惠券 List <SOItemInfo> soItems = ExternalDomainBroker.GetSOItemList(entity.OriginalSOSysNo.Value); soItems.ForEach(item => { if (item.PayType == ProductPayType.PointOnly) { pointOnly += item.Price.Value * item.Quantity.Value + item.PromotionAmount.Value; } else if (item.PayType == ProductPayType.MoneyOnly) { cashOnly += item.Price.Value * item.Quantity.Value + item.PromotionAmount.Value; } totalPromotionDiscount += item.PromotionAmount.Value * item.Quantity.Value; }); //表示只有仅积分或仅现金部分,没有均支持 if ((soBaseInfo.SOAmount + soBaseInfo.PromotionAmount) - (totalPromotionDiscount + pointOnly + cashOnly) == 0M) { //仅现金 if (pointOnly == 0 && cashOnly > 0) { originalSOCashPointRate = 1; } else //仅积分 { originalSOCashPointRate = 0; } } else if (soBaseInfo.CashPay - cashOnly == 0) { originalSOCashPointRate = 1; } else if (soBaseInfo.PointPay - pointOnly == 0) { originalSOCashPointRate = 0; } else { //表示均支持的现金部分与均支持的总额的比例 originalSOCashPointRate = (soBaseInfo.CashPay + soBaseInfo.PromotionAmount.Value - cashOnly) / (soBaseInfo.SOAmount.Value + soBaseInfo.PromotionAmount.Value - (totalPromotionDiscount + pointOnly + cashOnly)); } #endregion 计算 现金与积分比率 //根据单件退款额度,调整比率精度 int decimals = Decimal.Round(refundAmt, 0).ToString().Length + 2; //实际计算精度 decimal SOCashPointRate = Decimal.Round(originalSOCashPointRate, decimals); int refundPoint = Convert.ToInt32(Decimal.Round(refundAmt * (1 - SOCashPointRate) * pointExchangeRate, 0)); decimal refundCash = refundAmt - (Decimal.Round(refundAmt * (1 - SOCashPointRate), 2)); //积分补偿 decimal pointRedeem = -Decimal.Round((Decimal.Round(refundAmt * (1 - SOCashPointRate) * pointExchangeRate, 0) - (refundAmt * (1 - SOCashPointRate) * pointExchangeRate)) / pointExchangeRate, 2); refundCash += pointRedeem; #region 分配现金、礼品卡 if (refundPoint < 0) { refundPoint = 0; } if (entity.CashAmt > 0) { if (entity.GiftCardAmt == 0) { entity.CashAmt = refundCash; } else { if (entity.CashAmt > refundCash) { entity.GiftCardAmt = entity.CashAmt - refundCash; } else { entity.GiftCardAmt = refundCash - entity.CashAmt; } } } else { entity.GiftCardAmt = refundCash; } entity.PointAmt = refundPoint; if (entity.PointAmt > availPointAmt) { entity.PointAmt = availPointAmt; } #endregion 分配现金、礼品卡 #endregion 现金、礼品卡、积分金额划分 } #endregion SOItem } else //运费补偿及其他 { #region 运费补偿及其他 if (availShipPrice < entity.CashAmt.Value) { throw new BizException(ResouceManager.GetMessageString("RMA.RefundBalance", "OverfullShipFee")); } //if (entity.CashAmt.Value < 0) //{ // throw new BizException(ResouceManager.GetMessageString("RMA.RefundBalance", "NotGreaterThanRefundedAmt")); //} if (entity.PointAmt > 0) { throw new BizException(ResouceManager.GetMessageString("RMA.RefundBalance", "CannotUsePointsForRefundShipFee")); } #endregion 运费补偿及其他 } }