示例#1
0
        /// <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);
        }
示例#2
0
        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
        }
示例#3
0
        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);
        }