private int CalcTimesByQty(SaleDiscountRule data, int itemQty)
        {
            if (itemQty >= 0 && itemQty >= data.MinQty)
            {
                if (data.MinQty <= 0)
                {
                    return(1);
                }
                //判断循环标记
                if (data.IsCycle)
                {
                    if (itemQty > data.MaxQty)
                    {
                        return(data.MaxQty / data.MinQty);
                    }

                    return(itemQty / data.MinQty);
                }
                else
                {
                    return(1);
                }
            }

            //一次也不满足
            return(0);
        }
        //判断三级类别,品牌,商品ID条件满足
        private bool IsCategoryBrandMatch(SaleDiscountRule data, SOItemInfo soItem)
        {
            bool isItemMatch = true;
            //满足的条件数
            int matchedConditionCount = 3;

            if (data.C3SysNo > 0 && soItem.C3SysNo > 0)
            {
                isItemMatch = isItemMatch && (data.C3SysNo == soItem.C3SysNo);
            }
            else
            {
                matchedConditionCount--;
            }
            if (data.BrandSysNo > 0 && soItem.BrandSysNo > 0)
            {
                isItemMatch = isItemMatch && (data.BrandSysNo == soItem.BrandSysNo);
            }
            else
            {
                matchedConditionCount--;
            }
            if (data.ProductSysNo > 0 && data.ProductGroupSysNo > 0)
            {
                int soItemProductGroupSysNo = 0;
                //需要注意组商品概念
                isItemMatch = isItemMatch && (data.ProductSysNo == soItem.ProductSysNo || data.ProductGroupSysNo == soItemProductGroupSysNo);
            }
            else
            {
                matchedConditionCount--;
            }

            return(isItemMatch && matchedConditionCount > 0);
        }
        private int CalcTimesByAmt(SaleDiscountRule data, decimal itemAmt)
        {
            if (itemAmt >= 0 && itemAmt >= data.MinAmt)
            {
                if (data.MinAmt <= 0)
                {
                    return(1);
                }
                //判断循环标记
                if (data.IsCycle)
                {
                    if (itemAmt > data.MaxAmt)
                    {
                        return((int)(data.MaxAmt / data.MinAmt));
                    }
                    return((int)(itemAmt / data.MinAmt));
                }
                else
                {
                    return(1);
                }
            }

            //一次也不满足
            return(0);
        }
Example #4
0
        public void Update(SaleDiscountRule data)
        {
            DataCommand cmd = DataCommandManager.GetDataCommand("NewPromotion_SaleDiscountRule_Update");

            cmd.SetParameterValue(data);

            cmd.ExecuteNonQuery();
        }
Example #5
0
 public virtual void Update(SaleDiscountRule data)
 {
     CheckData(data);
     TransactionScopeFactory.TransactionAction(() =>
     {
         _daSaleDiscountRule.Update(data);
         //_promotionEngine.SaveActivity(data);
     });
 }
Example #6
0
        private void CheckExistsRule(SaleDiscountRule data)
        {
            int  c3SysNo      = data.C3SysNo ?? 0;
            int  brandSysNo   = data.BrandSysNo ?? 0;
            int  productSysNo = data.ProductSysNo ?? 0;
            int  excludeSysNo = data.SysNo ?? 0;
            bool exists       = true;

            //限定分类+品牌
            if (c3SysNo > 0 && brandSysNo > 0)
            {
                exists = _daSaleDiscountRule.CheckExistsProductScope_CategoryBrand(excludeSysNo, c3SysNo, brandSysNo);
                if (exists)
                {
                    //throw new BizException("已存在限定此分类+此品牌的有效销售规则,请不要重复设置。");
                    throw new BizException(ResouceManager.GetMessageString("MKT.SaleDiscountRule", "SaleDiscountRule_ExsistCategoryAndBrandActiveDiscountRule"));
                }
            }
            //限定分类
            else if (c3SysNo > 0)
            {
                exists = _daSaleDiscountRule.CheckExistsProductScope_Category(excludeSysNo, c3SysNo);
                if (exists)
                {
                    //throw new BizException("已存在限定此分类的有效销售规则,请不要重复设置。");
                    throw new BizException(ResouceManager.GetMessageString("MKT.SaleDiscountRule", "SaleDiscountRule_ExsistCategoryActiveDiscountRule"));
                }
            }
            //限定品牌
            else if (brandSysNo > 0)
            {
                exists = _daSaleDiscountRule.CheckExistsProductScope_Brand(excludeSysNo, brandSysNo);
                if (exists)
                {
                    //throw new BizException("已存在限定此品牌的有效销售规则,请不要重复设置。");
                    throw new BizException(ResouceManager.GetMessageString("MKT.SaleDiscountRule", "SaleDiscountRule_ExsistBrandActiveDiscountRule"));
                }
            }
            //限定商品(包含商品组的概念)
            else if (productSysNo > 0)
            {
                List <int> productSysNos = new List <int>(0);
                productSysNos.Add(productSysNo);
                var productInGroup = ExternalDomainBroker.GetProductsInSameGroupWithProductSysNo(productSysNo);
                if (productInGroup != null && productInGroup.Count > 0)
                {
                    productSysNos.Clear();
                    productSysNos = productInGroup.Select(item => item.SysNo).ToList();
                }
                exists = _daSaleDiscountRule.CheckExistsProductScope_Product(excludeSysNo, productSysNo);
                if (exists)
                {
                    //throw new BizException("已存在限定此商品或商品组的有效销售规则,请不要重复设置。");
                    throw new BizException(ResouceManager.GetMessageString("MKT.SaleDiscountRule", "SaleDiscountRule_ExsistActiveDiscountRule"));
                }
            }
        }
Example #7
0
        public void Insert(SaleDiscountRule data)
        {
            DataCommand cmd = DataCommandManager.GetDataCommand("NewPromotion_SaleDiscountRule_Insert");

            cmd.SetParameterValue(data);

            cmd.ExecuteNonQuery();
            data.SysNo = Convert.ToInt32(cmd.GetParameterValue("@SysNo"));
        }
        //判断单品规则是否满足
        private int IsSingleMatch(SaleDiscountRule data, SOItemInfo soItem, decimal discountAmt)
        {
            int matchedTimes = 0;

            if (data.RuleType == SaleDiscountRuleType.AmountRule)
            {
                decimal itemAmt = soItem.Quantity.Value * soItem.Price.Value - discountAmt;
                matchedTimes = CalcTimesByAmt(data, itemAmt);
            }
            else
            {
                matchedTimes = CalcTimesByQty(data, soItem.Quantity.Value);
            }

            return(matchedTimes);
        }
        /// <summary>
        /// 计算非单品标记
        /// </summary>
        /// <param name="data">规则</param>
        /// <param name="matchedItemList">商品列表</param>
        /// <param name="totalItemPrice">商品总额</param>
        /// <param name="totalItemQty">商品总数量</param>
        private List <SOPromotionDetailInfo> CalcNotSingleDiscount(SaleDiscountRule data, List <SOItemInfo> matchedItemList, decimal totalItemPrice, int totalItemQty, int matchedTimes, List <SOPromotionInfo> alreadyApplyPromoList)
        {
            //商品折扣总值
            decimal itemTotalDiscount = data.DiscountAmount * matchedTimes;
            //已分摊的折扣
            decimal itemDistributeDiscount = 0;

            //按商品金额比例分摊
            int index = 1;
            List <SOPromotionDetailInfo> promoDetailList = new List <SOPromotionDetailInfo>();

            foreach (var item in matchedItemList)
            {
                //计算商品已有折扣
                decimal discountAmt = GetItemDiscount(item, alreadyApplyPromoList);

                bool    isLast             = (index == matchedItemList.Count);
                decimal saleDiscountAmount = 0;
                if (isLast)
                {
                    //最后一个用总的折扣-已分摊的折扣
                    saleDiscountAmount = itemTotalDiscount - itemDistributeDiscount;
                }
                else
                {
                    saleDiscountAmount = (item.Price.Value * item.Quantity.Value - discountAmt) / totalItemPrice * itemTotalDiscount;
                    //保留两位小数,确保分摊无误差
                    saleDiscountAmount      = Math.Round(saleDiscountAmount, 2);
                    itemDistributeDiscount += saleDiscountAmount;
                }
                index++;
                var detail = GeneratePromoDetailInfo(item.ProductSysNo.Value, item.Quantity.Value, saleDiscountAmount);
                promoDetailList.Add(detail);
            }

            return(promoDetailList);
        }
 public virtual void Update(SaleDiscountRule data)
 {
     _bizSaleDiscountRule.Update(data);
 }
 public virtual void Insert(SaleDiscountRule data)
 {
     _bizSaleDiscountRule.Insert(data);
 }
Example #12
0
        private void CheckData(SaleDiscountRule data)
        {
            data.SysNo = data.SysNo ?? 0;
            if (string.IsNullOrWhiteSpace(data.ActivityName))
            {
                //throw new BizException("活动名称必须填写。");
                throw new BizException(ResouceManager.GetMessageString("MKT.SaleDiscountRule", "SaleDiscountRule_ActivityNameNotNull"));
            }
            if (data.BeginDate == null)
            {
                //throw new BizException("开始时间必须填写。");
                throw new BizException(ResouceManager.GetMessageString("MKT.SaleDiscountRule", "SaleDiscountRule_StartDateNotNull"));
            }

            if (data.EndDate == null)
            {
                //throw new BizException("结束时间必须填写。");
                throw new BizException(ResouceManager.GetMessageString("MKT.SaleDiscountRule", "SaleDiscountRule_EndDateNotNull"));
            }

            if (data.EndDate <= data.BeginDate)
            {
                //throw new BizException("结束时间必须大于开始时间。");
                throw new BizException(ResouceManager.GetMessageString("MKT.SaleDiscountRule", "SaleDiscountRule_EndDateMoreThanStartDate"));
            }
            if (data.EndDate.HasValue && data.EndDate.Value <= DateTime.Now)
            {
                //throw new BizException("结束时间必须大于当前时间。");
                throw new BizException(ResouceManager.GetMessageString("MKT.SaleDiscountRule", "SaleDiscountRule_EndDateMoreThanCurrentDate"));
            }

            if (!data.IsC3SysNoValid() &&
                !data.IsBrandSysNoValid() &&
                !data.IsProductSysNoValid())
            {
                //throw new BizException("商品分类,品牌,商品ID至少设置一项。");
                throw new BizException(ResouceManager.GetMessageString("MKT.SaleDiscountRule", "SaleDiscountRule_AtLeastCatgoryBrandID"));
            }

            if (data.RuleType == SaleDiscountRuleType.QtyRule)
            {
                if (data.MinQty <= 0)
                {
                    //throw new BizException("数量下限必须大于等于零。");
                    throw new BizException(ResouceManager.GetMessageString("MKT.SaleDiscountRule", "SaleDiscountRule_LowerLimitMoreThan0"));
                }
                if (data.MaxQty <= 0)
                {
                    //throw new BizException("数量上限必须大于等于零。");
                    throw new BizException(ResouceManager.GetMessageString("MKT.SaleDiscountRule", "SaleDiscountRule_UpperLimitMoreThan0"));
                }
                if (data.MaxQty < data.MinQty)
                {
                    //throw new BizException("数量上限必须大于等于数量下限");
                    throw new BizException(ResouceManager.GetMessageString("MKT.SaleDiscountRule", "SaleDiscountRule_UpperLimitMoreThanLowerLimit"));
                }
            }

            if (data.RuleType == SaleDiscountRuleType.AmountRule)
            {
                if (data.MinAmt <= 0)
                {
                    //throw new BizException("商品金额下限必须大于等于零。");
                    throw new BizException(ResouceManager.GetMessageString("MKT.SaleDiscountRule", "SaleDiscountRule_AmountLowerLimitMoreThan0"));
                }
                if (data.MaxAmt <= 0)
                {
                    //throw new BizException("商品金额上限必须大于等于零。");
                    throw new BizException(ResouceManager.GetMessageString("MKT.SaleDiscountRule", "SaleDiscountRule_AmountUpperLimitMoreThan0"));
                }
                if (data.MaxAmt < data.MinAmt)
                {
                    //throw new BizException("商品金额上限必须大于等于商品金额下限。");
                    throw new BizException(ResouceManager.GetMessageString("MKT.SaleDiscountRule", "SaleDiscountRule_AmountUpperLimitMoreThanAmountUpperLimit"));
                }
            }

            if (data.DiscountAmount > 0)
            {
                data.DiscountAmount = data.DiscountAmount * -1;
            }
            else if (data.DiscountAmount == 0)
            {
                //throw new BizException("销售折扣不能为零。");
                throw new BizException(ResouceManager.GetMessageString("MKT.SaleDiscountRule", "SaleDiscountRule_DiscountRuleNot0"));
            }


            CheckExistsRule(data);
        }
 public void UpdateSaleDiscountRule(SaleDiscountRule data)
 {
     _appServiceSaleDiscountRule.Update(data);
 }
 public void InsertSaleDiscountRule(SaleDiscountRule data)
 {
     _appServiceSaleDiscountRule.Insert(data);
 }
        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);
        }
        private SOPromotionDetailInfo CalcSingleDiscount(SaleDiscountRule data, SOItemInfo item, int matchedTimes)
        {
            decimal saleDiscountAmount = data.DiscountAmount * matchedTimes;

            return(GeneratePromoDetailInfo(item.ProductSysNo.Value, item.Quantity.Value, saleDiscountAmount));
        }