Пример #1
0
        /// <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);
        }
Пример #2
0
        /// <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);
                }
            }
        }
Пример #3
0
        /// <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 计算可退现金/积分/礼品卡
        }
Пример #4
0
        /// <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 运费补偿及其他
            }
        }