Beispiel #1
0
        /// <summary>
        /// 获取促销结果
        /// </summary>
        /// <param name="origComboList"></param>
        /// <param name="soInfo"></param>
        /// <param name="soItemList"></param>
        /// <param name="promotionInfoList"></param>
        protected virtual void GetPromotionListForSO(List <ComboInfo> origComboList, SOInfo soInfo, ref List <SOItemInfo> soItemList, ref List <SOPromotionInfo> promotionInfoList)
        {
            //1.取当前订单商品有效的Combo
            List <ComboInfo> validComboList = GetValidComboList(origComboList, soItemList);

            if (validComboList.Count == 0)
            {
                return;
            }

            //2.按照这些可以参与活动的Combo列表,得到所有的折扣列表: 遵循最大Combo折扣优先原则,而不是客户最大折扣优先原则
            List <ComboApplyInstance> comboApplyList = new List <ComboApplyInstance>();

            foreach (ComboInfo combo in validComboList)
            {
                ComboApplyInstance comboApply = new ComboApplyInstance();
                ComboInfo          comboClone = SerializationUtility.DeepClone <ComboInfo>(combo);
                comboApply.ComboSysNo = comboClone.SysNo.Value;
                //获取当前Combo在订单中最多可以存在多少套: 取订单中满足该Combo商品中最小数量
                int maxCount = int.MaxValue;
                foreach (ComboItem comboItem in comboClone.Items)
                {
                    SOItemInfo soItem   = soItemList.Find(f => f.ProductSysNo == comboItem.ProductSysNo);
                    int        curCount = soItem.Quantity.Value / comboItem.Quantity.Value;
                    if (curCount < maxCount)
                    {
                        maxCount = curCount;
                    }
                }
                comboApply.Qty = maxCount;
                decimal totalDiscount = 0.00m;
                foreach (ComboItem comboItem in comboClone.Items)
                {
                    totalDiscount += Math.Round(comboItem.Discount.Value * comboItem.Quantity.Value * maxCount, 2);
                }
                //取Combo Total Discount的绝对值
                comboApply.TotalDiscount = Math.Abs(totalDiscount);
                comboApplyList.Add(comboApply);
            }
            //3.得到折扣从大到小排序的列表
            var comboApplySortList = from p in comboApplyList
                                     orderby p.TotalDiscount descending
                                     select p;

            //4.取最大折扣的Combo
            ComboApplyInstance maxDiscountComboApply = comboApplySortList.First();
            ComboInfo          curCombo = validComboList.Find(f => f.SysNo.Value == maxDiscountComboApply.ComboSysNo);


            SOPromotionInfo promotionInfo = GetPromotionInfoForCurrentCombo(curCombo, maxDiscountComboApply, ref soItemList,
                                                                            promotionInfoList.Count + 1, soInfo.SysNo);

            if (promotionInfo != null)
            {
                promotionInfoList.Add(promotionInfo);
            }

            //5.轮询调用剩下的订单商品
            GetPromotionListForSO(validComboList, soInfo, ref soItemList, ref promotionInfoList);
        }
        /// <summary>
        /// 赠品方面的赠送处理
        /// </summary>
        /// <param name="promotionInfo"></param>
        /// <param name="soInfo"></param>
        /// <param name="canPromotionSOItemList"></param>
        /// <param name="rule"></param>
        protected void CalcGiftItemRule(SOPromotionInfo promotionInfo, SOInfo soInfo,
                                        List <SOItemInfo> canPromotionSOItemList, PSGiftItemRule rule)
        {
            //如果是只有1个主商品进行赠品,那么赠品可以全部绑定在这个这主商品下
            //如果是满足多个主商品才进行赠品,那么赠品无法绑定到各主商品下
            if (promotionInfo.SOPromotionDetails.Count == 1)
            {
                SOPromotionDetailInfo detail = promotionInfo.SOPromotionDetails[0];
                int masterProductSysNo       = rule.MasterProductSysNoList[0].Value;
                // (detail.MasterProductSysNo.Value == masterProductSysNo)
                //{
                //detail.GiftList = new List<SOPromotionInfo.GiftInfo>();
                //rule.GiftItemSysNoList.ForEach(f => detail.GiftList.Add(
                //    new SOPromotionInfo.GiftInfo()
                //    {
                //        ProductSysNo = f.GiftItemSysNo.Value,
                //        Quantity = f.GiftItemCount.HasValue ? f.GiftItemCount.Value : 1
                //    }));

                //}
            }

            rule.GiftItemSysNoList.ForEach(f => promotionInfo.GiftList.Add(
                                               new SOPromotionInfo.GiftInfo()
            {
                ProductSysNo = f.GiftItemSysNo.Value,
                Quantity     = f.GiftItemCount.HasValue ? f.GiftItemCount.Value : 1
            }));
        }
        private void CalcRecursive(List <SaleDiscountRule> allValidRule, List <SOItemInfo> itemList, int soSysNo, List <SOPromotionInfo> alreadyApplyPromoList, ref List <SOPromotionInfo> promoInfoList)
        {
            if (itemList.Count == 0)
            {
                return;
            }

            List <SOPromotionInfo> allPromoList = new List <SOPromotionInfo>();

            //加上其它已有优惠信息
            allPromoList.AddRange(alreadyApplyPromoList);
            //加上本类促销的优惠信息
            allPromoList.AddRange(promoInfoList);

            List <SOPromotionInfo> tempList = new List <SOPromotionInfo>();

            foreach (var rule in allValidRule)
            {
                SOPromotionInfo promotionInfo = ApplyingRule(rule, itemList, soSysNo, allPromoList);
                if (promotionInfo != null)
                {
                    tempList.Add(promotionInfo);
                }
            }
            if (tempList.Count > 0)
            {
                //找出最优惠的活动
                var             promoSortList     = tempList.OrderBy(p => p.DiscountAmount);
                SOPromotionInfo bestPromotionInfo = promoSortList.First();
                //将最优的活动添加到应用列表中
                promoInfoList.Add(bestPromotionInfo);

                //移除已参与应用的商品
                foreach (var promoItem in bestPromotionInfo.SOPromotionDetails)
                {
                    itemList.RemoveAll(item => item.ProductSysNo == promoItem.MasterProductSysNo);
                }
                //移除已参与的活动
                allValidRule.RemoveAll(rule => rule.SysNo == bestPromotionInfo.PromotionSysNo);
            }
            else
            {
                return;
            }

            //继续递归应用
            CalcRecursive(allValidRule, itemList, soSysNo, alreadyApplyPromoList, ref promoInfoList);
        }
 /// <summary>
 /// 优惠券方面的赠送处理
 /// </summary>
 /// <param name="promotionInfo"></param>
 /// <param name="soInfo"></param>
 /// <param name="canPromotionSOItemList"></param>
 /// <param name="rule"></param>
 protected void CalcCouponCodeRule(SOPromotionInfo promotionInfo, SOInfo soInfo,
                                   List <SOItemInfo> canPromotionSOItemList, PSCouponsRebateRule rule)
 {
     //如果是只有1个主商品进行赠送优惠券,那么赠送的优惠券可以全部绑定在这个这主商品下
     //如果是满足多个主商品才进行赠送优惠券,那么赠送的优惠券无法绑定到各主商品下
     if (promotionInfo.SOPromotionDetails.Count == 1)
     {
         if (!string.IsNullOrEmpty(rule.CouponCode))
         {
             SOPromotionDetailInfo detail = promotionInfo.SOPromotionDetails[0];
             //detail.CouponCodeList.Add(rule.CouponCode);
         }
     }
     if (!string.IsNullOrEmpty(rule.CouponCode))
     {
         promotionInfo.CouponCodeList.Add(rule.CouponCode);
     }
 }
        /// <summary>
        /// 积分方面的赠送处理
        /// </summary>
        /// <param name="promotionInfo"></param>
        /// <param name="soInfo"></param>
        /// <param name="canPromotionSOItemList"></param>
        /// <param name="rule"></param>
        protected void CalcPointRule(SOPromotionInfo promotionInfo, SOInfo soInfo,
                                     List <SOItemInfo> canPromotionSOItemList, PSPointScoreRule rule)
        {
            if (!rule.PointScore.HasValue)
            {
                return;
            }

            int canSendPoint = rule.PointScore.Value;

            //开始分摊积分
            decimal sumAmount = 0.00m;          //能够参与活动的商品总金额

            foreach (SOItemInfo item in canPromotionSOItemList)
            {
                sumAmount += Math.Round(item.OriginalPrice.Value * ((decimal)item.Quantity.Value), 2);
            }

            int allocatedPoint = 0;

            for (int i = 0; i < promotionInfo.SOPromotionDetails.Count; i++)
            {
                SOPromotionDetailInfo detail = promotionInfo.SOPromotionDetails[i];
                if (i < promotionInfo.SOPromotionDetails.Count - 1)
                {
                    SOItemInfo item         = soInfo.Items.Find(f => f.ProductSysNo == detail.MasterProductSysNo);
                    int        currentPoint = Convert.ToInt32(canSendPoint * (item.OriginalPrice.Value * item.Quantity.Value / sumAmount));
                    detail.GainPoint = currentPoint;
                    allocatedPoint  += currentPoint;
                }
                else
                {
                    detail.GainPoint = canSendPoint - allocatedPoint;
                }
            }
        }
Beispiel #6
0
        /// <summary>
        /// 子订单促销活动分摊
        /// </summary>
        /// <param name="masterSOInfo"></param>
        /// <param name="subSOInfo"></param>
        private void AssignSubSOPromotion(SOInfo subSOInfo)
        {
            #region 拆分订单的促销活动.
            //拆分订单的促销活动.
            if (CurrentSO.SOPromotions != null && CurrentSO.SOPromotions.Count > 0)
            {
                CurrentSO.SOPromotions.ForEach(promotion =>
                {
                    SOPromotionInfo promotionInfo = SerializationUtility.DeepClone(promotion);

                    promotionInfo.SOSysNo = subSOInfo.SysNo;
                    switch (promotion.PromotionType)
                    {
                    case SOPromotionType.Combo:
                        break;

                    case SOPromotionType.Coupon:
                        if (promotionInfo.SOPromotionDetails != null && promotionInfo.SOPromotionDetails.Count > 0)
                        {
                            //移出主商品不在子订单中的促销明细
                            promotionInfo.SOPromotionDetails.RemoveAll(d =>
                            {
                                return(!subSOInfo.Items.Exists(subSOItem =>
                                {
                                    return subSOItem.ProductSysNo == d.MasterProductSysNo;
                                }));
                            });
                            //计算子订单的总折扣
                            promotionInfo.DiscountAmount = promotionInfo.SOPromotionDetails.Sum <SOPromotionDetailInfo>(d => d.DiscountAmount);
                        }
                        if (promotionInfo.DiscountAmount == 0)
                        {
                            promotionInfo = null;
                        }
                        break;

                    case SOPromotionType.SelfGift:
                        //子订单中是否包含有赠品,没有就将促销设置为null.
                        if (!promotionInfo.GiftList.Exists(g =>
                        {
                            return(subSOInfo.Items.Exists(item =>
                            {
                                return item.ProductType == SOProductType.SelfGift && g.ProductSysNo == item.ProductSysNo;
                            }));
                        }))
                        {
                            promotionInfo = null;
                        }
                        break;

                    case SOPromotionType.VendorGift:
                    case SOPromotionType.Accessory:
                        //子订单是否包含附件或厂商赠品,如果没有就设置为null
                        if (promotionInfo.SOPromotionDetails != null && promotionInfo.GiftList.Count > 0)
                        {
                            //移出不在子订单中的附件
                            promotionInfo.GiftList.RemoveAll(g =>
                            {
                                return(!subSOInfo.Items.Exists(subSOItem =>
                                {
                                    return promotion.PromotionType == SOPromotionType.Accessory ?
                                    (subSOItem.ProductSysNo == g.ProductSysNo && subSOItem.ProductType == SOProductType.Accessory) :
                                    (subSOItem.ProductSysNo == g.ProductSysNo && subSOItem.ProductType == SOProductType.Gift);
                                }));
                            });
                            ////移出附件不在子订单中的附件明细
                            //if (promotionInfo.GiftList.Count < 1)
                            //{
                            //    promotionInfo.SOPromotionDetails.RemoveAll(d =>
                            //    {
                            //        d.GiftList.RemoveAll(dg =>
                            //        {
                            //            return !promotionInfo.GiftList.Exists(g =>
                            //            {
                            //                return g.ProductSysNo == dg.ProductSysNo;
                            //            });
                            //        });
                            //        return d.GiftList.Count == 0;
                            //    });
                            //}
                        }
                        if (promotionInfo.GiftList.Count == 0)
                        {
                            promotionInfo = null;
                        }
                        break;
                    }
                    if (promotionInfo != null)
                    {
                        subSOInfo.SOPromotions.Add(promotionInfo);
                    }
                });
            }
            #endregion
        }
        private SOPromotionInfo ApplyingRule(SaleDiscountRule rule, List <SOItemInfo> itemList, int soSysNo, List <SOPromotionInfo> alreadyApplyPromoList)
        {
            List <SOPromotionDetailInfo> promoDetailList = new List <SOPromotionDetailInfo>();
            decimal           totalAmt        = 0;
            int               totalQty        = 0;
            List <SOItemInfo> matchedItemList = new List <SOItemInfo>(itemList.Count);

            foreach (var item in itemList)
            {
                //判断三级类别,品牌,商品ID条件满足
                bool isItemMatch = IsCategoryBrandMatch(rule, item);
                if (isItemMatch)
                {
                    //加入到匹配商品列表
                    matchedItemList.Add(item);
                    if (!rule.IsSingle)
                    {
                        //计算商品已有折扣
                        decimal discountAmt = GetItemDiscount(item, alreadyApplyPromoList);

                        //非单品标记时,计算总金额和总数量
                        totalAmt += item.Quantity.Value * item.Price.Value - discountAmt;
                        totalQty += item.Quantity.Value;
                    }
                }
            }
            //应用规则
            if (rule.IsSingle)
            {
                foreach (var item in matchedItemList)
                {
                    //计算商品已有折扣
                    decimal discountAmt  = GetItemDiscount(item, alreadyApplyPromoList);
                    int     matchedTimes = IsSingleMatch(rule, item, discountAmt);
                    if (matchedTimes > 0)
                    {
                        var promoDetail = CalcSingleDiscount(rule, item, matchedTimes);
                        promoDetailList.Add(promoDetail);
                    }
                }
            }
            else
            {
                //非单品,根据规则类型进一步判断
                if (totalAmt > 0 && totalQty > 0)
                {
                    int matchedTimes = 0;
                    if (rule.RuleType == SaleDiscountRuleType.AmountRule)
                    {
                        matchedTimes = CalcTimesByAmt(rule, totalAmt);
                    }
                    else
                    {
                        matchedTimes = CalcTimesByQty(rule, totalQty);
                    }
                    if (matchedTimes > 0)
                    {
                        var detailList = CalcNotSingleDiscount(rule, matchedItemList, totalAmt, totalQty, matchedTimes, alreadyApplyPromoList);
                        promoDetailList.AddRange(detailList);
                    }
                }
            }

            SOPromotionInfo promotionInfo = null;

            if (promoDetailList.Count > 0)
            {
                //生成SOPromotionInfo信息
                promotionInfo = new SOPromotionInfo();
                promotionInfo.PromotionType  = SOPromotionType.SaleDiscountRule;
                promotionInfo.PromotionSysNo = rule.SysNo;
                promotionInfo.PromotionName  = rule.ActivityName;
                promotionInfo.DiscountAmount = -1 * promoDetailList.Sum(item => item.DiscountAmount.Value);
                promotionInfo.GainPoint      = 0;
                promotionInfo.Priority       = 0;
                promotionInfo.Time           = 1;
                promotionInfo.SOSysNo        = soSysNo;
                promotionInfo.VendorSysNo    = rule.VendorSysNo ?? 0;
                promotionInfo.PromoRuleData  = SerializationUtility.XmlSerialize(rule);
                promotionInfo.Discount       = promotionInfo.DiscountAmount;

                promotionInfo.SOPromotionDetails = promoDetailList;
            }

            return(promotionInfo);
        }
Beispiel #8
0
        /// <summary>
        /// 根据当前Combo,得到该Combo在订单中的SOPromotionInfo
        /// </summary>
        /// <param name="curCombo"></param>
        /// <param name="comboApply"></param>
        /// <param name="soItemList"></param>
        /// <param name="priority"></param>
        /// <param name="soSysNo"></param>
        /// <returns></returns>
        protected virtual SOPromotionInfo GetPromotionInfoForCurrentCombo(ComboInfo curCombo,
                                                                          ComboApplyInstance comboApply, ref List <SOItemInfo> soItemList, int priority, int?soSysNo)
        {
            SOPromotionInfo promotionInfo = null;

            int maxCount = comboApply.Qty;

            if (maxCount > 0)
            {
                //说明当前订单剩余商品还可以满足这个Combo
                promotionInfo = new SOPromotionInfo();
                promotionInfo.PromotionType  = SOPromotionType.Combo;
                promotionInfo.Combo          = curCombo;
                promotionInfo.PromotionSysNo = curCombo.SysNo.Value;
                promotionInfo.PromotionName  = curCombo.Name != null ? curCombo.Name.Content : null;
                promotionInfo.DiscountAmount = -Math.Abs(comboApply.TotalDiscount);
                promotionInfo.GainPoint      = 0;
                promotionInfo.Priority       = priority;
                promotionInfo.SOSysNo        = soSysNo;
                promotionInfo.Time           = maxCount;
                if (promotionInfo.Time > 0)
                {
                    promotionInfo.Discount = promotionInfo.DiscountAmount / promotionInfo.Time;
                }

                StringBuilder promotionNote = new StringBuilder();

                promotionInfo.SOPromotionDetails = new List <SOPromotionDetailInfo>();
                foreach (ComboItem comboItem in curCombo.Items)
                {
                    SOPromotionDetailInfo promotionDetail = new SOPromotionDetailInfo();
                    promotionDetail.DiscountAmount        = Math.Abs(Math.Round(comboItem.Discount.Value * comboItem.Quantity.Value * maxCount, 2));
                    promotionDetail.GainPoint             = 0;
                    promotionDetail.MasterProductQuantity = comboItem.Quantity.Value * maxCount;
                    promotionDetail.MasterProductSysNo    = comboItem.ProductSysNo.Value;
                    //promotionDetail.MasterProductType = SOProductType.Product;
                    promotionInfo.SOPromotionDetails.Add(promotionDetail);

                    promotionNote.AppendFormat("{0},{1},-{2};", promotionDetail.MasterProductQuantity, promotionDetail.MasterProductSysNo, promotionDetail.DiscountAmount);

                    //最重要的一点:要从soItemList中减掉这些已经做了折扣的商品及数量
                    //如果数量没减完,则在soItemList中保留该Item,但是数量要减掉;如果数量减完,则从soItemList中Remove掉改Item
                    List <SOItemInfo> needRemoveSOItemList = new List <SOItemInfo>();
                    foreach (SOItemInfo soItem in soItemList)
                    {
                        if (soItem.ProductSysNo == comboItem.ProductSysNo)
                        {
                            soItem.OriginalPrice = soItem.OriginalPrice + comboItem.Discount; //有折扣总价减去折扣 Bug:89610
                            if (soItem.Quantity > comboItem.Quantity.Value * maxCount)
                            {
                                soItem.Quantity = soItem.Quantity - comboItem.Quantity.Value * maxCount;
                            }
                            else
                            {
                                needRemoveSOItemList.Add(soItem);
                            }
                        }
                    }
                    foreach (SOItemInfo soItem in needRemoveSOItemList)
                    {
                        soItemList.Remove(soItem);
                    }
                }
                promotionInfo.Note = promotionNote.ToString();
            }
            return(promotionInfo);
        }
        /// <summary>
        /// 金额方面的折扣处理:目前价格方面的折扣与总金额方面的折扣不可并存
        /// </summary>
        /// <param name="promotionInfo"></param>
        /// <param name="soInfo"></param>
        /// <param name="canPromotionSOItemList"></param>
        protected void CalcAmountRule(SOPromotionInfo promotionInfo, SOInfo soInfo,
                                      List <SOItemInfo> canPromotionSOItemList, CouponsInfo couponsInfo)
        {
            PSOrderAmountDiscountRule  ruleAmount    = couponsInfo.OrderAmountDiscountRule;
            List <PSPriceDiscountRule> rulePriceList = couponsInfo.PriceDiscountRule;
            decimal sumAllItemPriceAmount            = 0.00m;            //能够参与活动的商品总金额,所有商品原价乘以数量的总金额
            decimal sumAllOrderItemAmount            = 0.00m;            //所有订单商品的商品总金额,用于计算优惠券平摊金额
            decimal saleRulePromotionAmount          = 0.00m;            //除去优惠券后,其它优惠金额总额
            decimal soItemAmount       = soInfo.BaseInfo.SOAmount.Value; //订单商品实际总金额,已经扣去了Combo等折扣
            decimal?orderMaxDiscount   = null;                           //本活动中设置的每单折扣上限
            decimal calcDiscountAmount = 0.00m;                          //计算出来的折扣

            foreach (SOItemInfo item in canPromotionSOItemList)
            {
                sumAllItemPriceAmount += Math.Round(item.OriginalPrice.Value * ((decimal)item.Quantity.Value), 2);
            }

            foreach (var item in soInfo.Items)
            {
                if (item.ProductType.Value == SOProductType.Product || item.ProductType.Value == SOProductType.ExtendWarranty)
                {
                    sumAllOrderItemAmount   += item.OriginalPrice.Value * ((decimal)item.Quantity.Value);
                    saleRulePromotionAmount += item.PromotionAmount ?? 0.00M;
                }
            }

            #region 计算总金额方面的折扣
            if (ruleAmount != null && ruleAmount.OrderAmountDiscountRank != null && ruleAmount.OrderAmountDiscountRank.Count > 0)
            {
                calcDiscountAmount = 0.00m;

                orderMaxDiscount = ruleAmount.OrderMaxDiscount;
                if (ruleAmount.OrderAmountDiscountRank != null && ruleAmount.OrderAmountDiscountRank.Count > 0)
                {
                    //首先确认取折扣信息时,根据限定金额Amount倒序
                    var ruleAmountDiscountRankNew = from p in ruleAmount.OrderAmountDiscountRank
                                                    orderby p.OrderMinAmount descending
                                                    select p;
                    foreach (OrderAmountDiscountRank rank in ruleAmountDiscountRankNew)
                    {
                        decimal minAmount = rank.OrderMinAmount.HasValue ? rank.OrderMinAmount.Value : 0.00m;

                        if (couponsInfo.ProductRangeType == CouponsProductRangeType.AllProducts && sumAllItemPriceAmount < minAmount)
                        {
                            //普通订单商品(SOItemInfo.ProductType==SOProductType.Product的商品)的总金额与限定金额值比较,跳过不满足条件价格条件。
                            continue;
                        }
                        if (soItemAmount >= minAmount)
                        {
                            if (rank.DiscountType.Value == PSDiscountTypeForOrderAmount.OrderAmountPercentage)
                            {
                                calcDiscountAmount = Math.Round(soItemAmount * rank.DiscountValue.Value, 2);
                            }
                            if (rank.DiscountType.Value == PSDiscountTypeForOrderAmount.OrderAmountDiscount)
                            {
                                calcDiscountAmount = Math.Round(rank.DiscountValue.Value, 2);
                            }
                            break;
                        }
                    }
                }
            }
            #endregion

            #region 计算商品价格方面的折扣
            if (rulePriceList != null && rulePriceList.Count > 0)
            {
                calcDiscountAmount = 0.00m;

                List <PSPriceDiscountRule> discountList = rulePriceList.FindAll(f => f.DiscountType == PSDiscountTypeForProductPrice.ProductPriceDiscount);
                List <PSPriceDiscountRule> finalList    = rulePriceList.FindAll(f => f.DiscountType == PSDiscountTypeForProductPrice.ProductPriceFinal);
                //如果商品价格是直接折扣
                if (discountList != null && discountList.Count > 0)
                {
                    var discountListNew = from p in discountList
                                          orderby p.MinQty descending
                                          select p;
                    foreach (SOItemInfo item in canPromotionSOItemList)
                    {
                        foreach (PSPriceDiscountRule prule in discountListNew)
                        {
                            int minQty = prule.MinQty.HasValue ? prule.MinQty.Value : 1;
                            if (item.Quantity >= minQty)
                            {
                                calcDiscountAmount += Math.Round(prule.DiscountValue.Value * item.Quantity.Value, 2);
                                break;
                            }
                        }
                    }
                }

                //如果是最终售价
                if (finalList != null && finalList.Count > 0)
                {
                    var finalListNew = from p in finalList
                                       orderby p.MinQty descending
                                       select p;
                    foreach (SOItemInfo item in canPromotionSOItemList)
                    {
                        foreach (PSPriceDiscountRule prule in finalListNew)
                        {
                            int minQty = prule.MinQty.HasValue ? prule.MinQty.Value : 1;
                            if (item.Quantity >= minQty)
                            {
                                //当单个商品 最终售价大于商品售价时
                                if (prule.DiscountValue.Value >= item.Price.Value)
                                {
                                    calcDiscountAmount += 0.00m;
                                }
                                else
                                {
                                    calcDiscountAmount += Math.Round((item.Price.Value - prule.DiscountValue.Value) * item.Quantity.Value, 2);
                                }
                                break;
                            }
                        }
                    }
                }
            }
            #endregion

            #region 得到真正最终可以折扣的金额
            decimal canDiscountAmount = calcDiscountAmount;
            if (orderMaxDiscount.HasValue)
            {
                if (calcDiscountAmount <= orderMaxDiscount.Value)
                {
                    canDiscountAmount = calcDiscountAmount;
                }
                else
                {
                    canDiscountAmount = Math.Round(orderMaxDiscount.Value, 2);
                }
            }

            promotionInfo.DiscountAmount = Math.Abs(canDiscountAmount);
            #endregion

            #region 开始分摊折扣金额
            if (promotionInfo.DiscountAmount == 0.00m)
            {
                return;
            }
            //最后一个Item要特殊处理,要用总折扣减去前边所有item的折扣合
            decimal allocatedDiscount        = 0.00m;
            decimal actualAllItemPriceAmount = sumAllOrderItemAmount + saleRulePromotionAmount;
            if (actualAllItemPriceAmount != 0)
            {
                for (int i = 0; i < promotionInfo.SOPromotionDetails.Count; i++)
                {
                    SOPromotionDetailInfo detail = promotionInfo.SOPromotionDetails[i];
                    SOItemInfo            item   = soInfo.Items.Find(f => f.ProductSysNo == detail.MasterProductSysNo);
                    //除去套餐优惠金额
                    decimal pTotal = item.OriginalPrice.Value * item.Quantity.Value + item.PromotionAmount ?? 0;
                    if (i < promotionInfo.SOPromotionDetails.Count - 1)
                    {
                        //decimal currentDiscount=decimal.Floor((canDiscountAmount * (pTotal / sumAllItemPriceAmount)) * 100) / 100;
                        decimal currentDiscount = canDiscountAmount * (pTotal / actualAllItemPriceAmount); //只保留小数点后两位,Bug:89610
                        currentDiscount       = Math.Abs(currentDiscount);
                        currentDiscount       = Math.Min(currentDiscount, pTotal);
                        detail.DiscountAmount = currentDiscount;
                        allocatedDiscount    += currentDiscount;
                    }
                    else
                    {
                        detail.DiscountAmount = Math.Abs(canDiscountAmount - allocatedDiscount);
                        detail.DiscountAmount = Math.Min(detail.DiscountAmount.Value, pTotal);
                    }
                }
            }
            #endregion
        }