/// <summary> /// 接收退货 /// </summary> /// <param name="rmaRequestSysNo">退换货申请单编号</param> /// <param name="userSysNo">操作人用户</param> /// <returns></returns> public static RMARequestInfo Receive(int rmaRequestSysNo, LoginUser operateUser) { RMARequestInfo request = LoadWithRequestSysNo(rmaRequestSysNo, operateUser.SellerSysNo); if (request == null) { throw new BusinessException(L("未找到编号为【{0}】的退换货申请单", rmaRequestSysNo)); } if (request.Status != RMARequestStatus.Origin) { throw new BusinessException(L("不能接收非“待处理”状态的申请单")); } if (request.Registers == null || request.Registers.Count <= 0) { throw new BusinessException(L("没有需要退换货的商品")); } //TODO: 虚拟仓库编码 request.ReceiveWarehouse = "90"; request.RecvTime = DateTime.Now; request.RecvUserSysNo = operateUser.UserSysNo; request.RecvUserName = operateUser.UserDisplayName; //收货后状态变成“处理中”,这个时候可以进行退货或退款操作 request.Status = RMARequestStatus.Handling; bool isWithin7Days = false; if (request.CustomerSendTime.HasValue) { isWithin7Days = request.CustomerSendTime.Value.AddDays(-7) < DateTime.Now; } List <SOItemInfo> soItems = SOService.GetSOItemInfoList(request.SOSysNo.Value); SOItemInfo soItem = null; foreach (var reg in request.Registers) { reg.OwnBy = RMAOwnBy.Customer; reg.Location = RMALocation.Self; reg.LocationWarehouse = request.ReceiveWarehouse; reg.IsWithin7Days = isWithin7Days; reg.Status = request.Status; soItem = soItems.Find(x => x.ProductSysNo == reg.ProductSysNo.Value && x.ProductType == reg.SoItemType.Value); if (soItem == null) { throw new BusinessException(L("订单中不存在申请退换货的商品:{0}【1】", reg.ProductName, reg.ProductID)); } reg.Cost = soItem.Cost; } ; UpdateWithRegisters(request); return(request); }
private static void CalcRefundAmount(RMARefundInfo refundInfo, RMARequestInfo request) { refundInfo.RefundItems = new List <RMARefundItemInfo>(); SOInfo soInfo = SOService.GetSOInfo(request.SOSysNo.Value); //计算积分支付比例 decimal originalSOCashPointRate = soInfo.PointAmt / ( soInfo.Amount.SOAmt + soInfo.Amount.ShipPrice - Math.Abs(soInfo.PromotionAmt) - Math.Abs(soInfo.Amount.DiscountAmt)); refundInfo.SOCashPointRate = Decimal.Round(originalSOCashPointRate, 4); List <SOItemInfo> soItems = SOService.GetSOItemInfoList(request.SOSysNo.Value); //计算总计应退金额,包括应退现金+积分+余额 decimal totalRefundProductValue = Decimal.Round(request.Registers.Sum(registerInfo => { var soItem = soItems.Find(x => x.ProductSysNo == registerInfo.ProductSysNo.Value && x.ProductType == registerInfo.SoItemType.Value); return(soItem.OriginalPrice - Math.Abs(soItem.PromotionDiscount) - Math.Abs(soItem.DiscountAmt / soItem.Quantity)); }), 2); decimal assignedRefundCashAmt = 0m; refundInfo.OrgCashAmt = 0m; refundInfo.OrgPointAmt = 0; refundInfo.PointPay = 0; for (var index = 0; index < request.Registers.Count; index++) { RMARegisterInfo registerInfo = request.Registers[index]; RMARefundItemInfo refundItem = new RMARefundItemInfo(); var soItem = soItems.Find(x => x.ProductSysNo == registerInfo.ProductSysNo.Value && x.ProductType == registerInfo.SoItemType.Value); refundItem.OrgPrice = soItem.OriginalPrice; refundItem.OrgPoint = soItem.Point; refundItem.PointType = soItem.PointType; refundItem.UnitDiscount = soItem.DiscountAmt / soItem.Quantity; refundItem.ProductValue = (soItem.OriginalPrice - Math.Abs(soItem.PromotionDiscount)) - Math.Abs(refundItem.UnitDiscount.Value); refundItem.RefundCost = soItem.Cost; refundItem.RefundCostWithoutTax = soItem.UnitCostWithoutTax; refundItem.RefundPoint = soItem.Point; refundItem.RegisterSysNo = registerInfo.SysNo; if (totalRefundProductValue <= 0m) { refundItem.RefundCash = 0m; } else { //按商品价值比例计算单个商品退款金额 if (index < request.Registers.Count - 1) { refundItem.RefundCash = ((refundItem.ProductValue / totalRefundProductValue) * refundInfo.CashAmt * (1 - originalSOCashPointRate)).Value; } else { refundItem.RefundCash = refundInfo.CashAmt.Value - assignedRefundCashAmt; } } refundItem.RefundPrice = refundItem.RefundCash; refundItem.RefundPoint = Convert.ToInt32(Decimal.Round((refundItem.RefundCash * originalSOCashPointRate).Value, 0)); refundItem.RefundPriceType = RefundPriceType.OriginPrice; refundInfo.OrgCashAmt += refundItem.RefundCash.Value; refundInfo.OrgPointAmt += (-1) * refundItem.RefundPoint.Value; refundInfo.PointPay += refundInfo.OrgPointAmt; assignedRefundCashAmt += refundItem.RefundCash.Value; refundInfo.RefundItems.Add(refundItem); } #region 计算顾客积分归还积分折合现金 refundInfo.DeductPointFromAccount = 0; refundInfo.DeductPointFromCurrentCash = 0m; if (refundInfo.OrgPointAmt < 0) { CustomerBasicInfo customer = CustomerService.GetCustomerInfo(refundInfo.CustomerSysNo.Value); if (refundInfo.OrgPointAmt * -1 < customer.ValidScore) { refundInfo.DeductPointFromAccount = refundInfo.OrgPointAmt * -1; } else { refundInfo.DeductPointFromAccount = customer.ValidScore; refundInfo.DeductPointFromCurrentCash = Decimal.Round(((refundInfo.OrgPointAmt ?? 0) * -1 - (customer.ValidScore ?? 0)) / CustomerService.GetPointToMoneyRatio(), 2); } } #endregion }
public static RMARefundInfo Create(RMARefundInfo refundInfo, LoginUser operateUser) { if (!refundInfo.SOSysNo.HasValue) { throw new BusinessException(L("订单号不能为空")); } if (refundInfo.RefundPayType == RefundPayType.BankRefund) { if (string.IsNullOrWhiteSpace(refundInfo.CardOwnerName)) { throw new BusinessException(L("收款人不能为空")); } if (string.IsNullOrWhiteSpace(refundInfo.BankName)) { throw new BusinessException(L("银行名称不能为空")); } if (string.IsNullOrWhiteSpace(refundInfo.CardNumber)) { throw new BusinessException(L("银行卡号不能为空")); } if (!refundInfo.CashAmt.HasValue || refundInfo.CashAmt.Value < 0m) { throw new BusinessException(L("退款金额不能小于0")); } var maxRefundAmt = Decimal.Round(refundInfo.RefundItems.Sum(x => x.ProductValue.Value), 2, MidpointRounding.AwayFromZero); if (refundInfo.CashAmt > maxRefundAmt) { throw new BusinessException(L("实际退款金额不能大于应退金额:{0}", maxRefundAmt)); } } #region 检查订单最大可退金额 //数据check不包含在事务中 using (ITransaction trans = TransactionManager.SuppressTransaction()) { var soItemList = SOService.GetSOItemInfoList(refundInfo.SOSysNo.Value); decimal maxRMARefundAmt = soItemList.Sum(soItem => { return((soItem.OriginalPrice - Math.Abs(soItem.PromotionDiscount) - Math.Abs(soItem.DiscountAmt / soItem.Quantity)) * soItem.Quantity); }); decimal thisRefundAmt = Math.Abs(refundInfo.CashAmt.GetValueOrDefault()) + Math.Abs(refundInfo.PointPay.GetValueOrDefault() * pointExchangeRate) + Math.Abs(refundInfo.GiftCardAmt.GetValueOrDefault()); decimal historyRefundAmt = 0m; var validRefundList = RMARefundDA.GetValidRefundListBySOSysNo(refundInfo.SOSysNo.Value); if (validRefundList != null && validRefundList.Count > 0) { historyRefundAmt = validRefundList.Sum(info => { return(Math.Abs(info.CashAmt.GetValueOrDefault()) + Math.Abs(info.PointPay.GetValueOrDefault() * pointExchangeRate) + Math.Abs(info.GiftCardAmt.GetValueOrDefault())); }); } if (thisRefundAmt + historyRefundAmt > Decimal.Round(maxRMARefundAmt, 2)) { throw new BusinessException(L("超过原始购物订单#{0}的最大可退金额{1},不能再退款", refundInfo.SOSysNo, Decimal.Round(maxRMARefundAmt, 2))); } trans.Complete(); } #endregion refundInfo.Status = RMARefundStatus.WaitingAudit; refundInfo.SOIncomeStatus = SOIncomeStatus.Origin; refundInfo.InUserSysNo = operateUser.UserSysNo; refundInfo.InUserName = operateUser.UserDisplayName; using (ITransaction trans = TransactionManager.Create()) { int newSysNo = RMARefundDA.CreateNewRefundSysNo(); refundInfo.SysNo = newSysNo; refundInfo.RefundID = String.Format("R3{0:00000000}", newSysNo); //创建RMA Refund记录 RMARefundDA.Create(refundInfo); //创建退款银行信息 SOIncomeRefundInfo soIncomeRefundInfo = new SOIncomeRefundInfo() { OrderType = refundInfo.OrderType, OrderSysNo = refundInfo.SysNo, SOSysNo = refundInfo.SOSysNo, BankName = refundInfo.BankName, CardNumber = refundInfo.CardNumber, CardOwnerName = refundInfo.CardOwnerName, RefundPayType = refundInfo.RefundPayType, CreateUserSysNo = operateUser.UserSysNo, CreateUserName = operateUser.UserDisplayName, Status = RefundStatus.Origin, HaveAutoRMA = false, RefundCashAmt = refundInfo.CashAmt, RefundPoint = refundInfo.PointPay, RefundGiftCard = refundInfo.GiftCardAmt }; RMARefundDA.CreateRefundBankInfo(soIncomeRefundInfo); if (refundInfo.RefundItems != null) { foreach (var item in refundInfo.RefundItems) { item.RefundSysNo = refundInfo.SysNo; RMARefundDA.CreateItem(item); } } trans.Complete(); } return(refundInfo); }