Exemplo n.º 1
0
        public void Calculate(ref OrderInfo order)
        {
            CalculateDiscountAmount(order);

            Dictionary <int, List <OrderInfo> > merchantOrderList = new Dictionary <int, List <OrderInfo> >();

            #region 1、分拆商家订单

            if (order.SubOrderList != null)
            {
                foreach (var subOrder in order.SubOrderList)
                {
                    int merchantSysNo = Convert.ToInt32(subOrder.Key.Split('|')[0]);
                    if (!merchantOrderList.ContainsKey(merchantSysNo))
                    {
                        merchantOrderList[merchantSysNo] = new List <OrderInfo>();
                    }
                    merchantOrderList[merchantSysNo].Add(subOrder.Value);
                }
            }

            #endregion

            #region 2、计算商家优惠券

            List <CustomerCouponInfo> merchantCouponList = PromotionDA.GetMerchantCouponCodeList(order.Customer.SysNo);
            if (merchantCouponList != null)
            {
                foreach (var merchantOrder in merchantOrderList)
                {
                    List <CustomerCouponInfo> currMerchantCouponList = merchantCouponList.FindAll(m => m.MerchantSysNo == merchantOrder.Key);
                    if (currMerchantCouponList == null || currMerchantCouponList.Count == 0)
                    {
                        continue;
                    }
                    foreach (var coupon in currMerchantCouponList)
                    {
                        bool canUse = false;
                        #region 检查商品限制,是否可用
                        List <int> productSysNoList = new List <int>();
                        foreach (var itemOrder in merchantOrder.Value)
                        {
                            foreach (var itemGroup in itemOrder.OrderItemGroupList)
                            {
                                itemGroup.ProductItemList.ForEach(product =>
                                {
                                    productSysNoList.Add(product.ProductSysNo);
                                });
                            }
                        }
                        List <CouponSaleRules> couponSaleRulesList = PromotionDA.GetCouponSaleRulesList(coupon.CouponCode);
                        if (couponSaleRulesList == null || couponSaleRulesList.Count == 0)
                        {
                            //不存在排除或指定商品,全网通用
                            canUse = true;
                        }
                        else
                        {
                            foreach (int productSysNo in productSysNoList)
                            {
                                if (couponSaleRulesList.Exists(m => m.ProductSysNo == productSysNo))
                                {
                                    if (couponSaleRulesList[0].RelationType == "N")
                                    {
                                        //存在排除的商品,不可用
                                        canUse = false;
                                        break;
                                    }
                                    else
                                    {
                                        //存在指定的商品,可用
                                        canUse = true;
                                        break;
                                    }
                                }
                            }
                        }
                        #endregion
                        if (canUse)
                        {
                            if (CheckCouponCodeCanUse(coupon.CouponCode, order.Customer))
                            {
                                foreach (var itemOrder in merchantOrder.Value)
                                {
                                    if (itemOrder.MerchantCouponList == null)
                                    {
                                        itemOrder.MerchantCouponList = new List <CustomerCouponInfo>();
                                    }
                                    itemOrder.MerchantCouponList.Add(coupon);
                                }
                            }
                        }
                    }
                }
            }

            #endregion

            #region 3、商家订单使用优惠券

            foreach (var merchantOrder in merchantOrderList)
            {
                MerchantCoupon merchantCoupon = null;
                if (order.MerchantCouponCodeList != null)
                {
                    merchantCoupon = order.MerchantCouponCodeList.Find(m => m.MerchantSysNo == merchantOrder.Key);
                }
                if (merchantCoupon == null)
                {
                    continue;
                }
                string couponCode = merchantCoupon.CouponCode.ToUpper().Trim();

                #region 1、初次筛选该优惠券号码对于前用户是否能用
                CustomerCouponInfo customerCoupon = PromotionDA.GetCouponSaleRules(order.Customer.SysNo, couponCode);
                if (customerCoupon == null)
                {
                    SetCouponError(ref order, LanguageHelper.GetText("您没有此优惠券{0}", order.LanguageCode), merchantCoupon.CouponName);
                    continue;
                }
                if (customerCoupon.IsExpired)
                {
                    SetCouponError(ref order, LanguageHelper.GetText("此优惠券{0}已过期", order.LanguageCode), merchantCoupon.CouponName);
                    continue;
                }
                if (customerCoupon.CustomerMaxFrequency.HasValue && customerCoupon.UsedCount >= customerCoupon.CustomerMaxFrequency.Value)
                {
                    SetCouponError(ref order, LanguageHelper.GetText("您已达到使用优惠券{0}的次数上限", order.LanguageCode), merchantCoupon.CouponName);
                    continue;
                }

                int totalUsedCount = 0;
                if (customerCoupon.CodeType.Trim().ToUpper() == "C")
                {
                    totalUsedCount = PromotionDA.GetCouponCodeTotalUsedCount(couponCode);
                }
                else
                {
                    totalUsedCount = PromotionDA.GetCouponTotalUsedCount(customerCoupon.CouponSysNo);
                }
                if (customerCoupon.WebsiteMaxFrequency.HasValue && totalUsedCount >= customerCoupon.WebsiteMaxFrequency)
                {
                    SetCouponError(ref order, LanguageHelper.GetText("此优惠券{0}的已达到全网使用次数上限", order.LanguageCode), merchantCoupon.CouponName);
                    continue;
                }
                #endregion

                #region 2、获取该优惠券号码对应的优惠券活动所有信息
                CouponInfo coupon = PromotionDA.GetComboInfoByCouponCode(couponCode);
                if (coupon.SaleRulesEx.CustomerMaxFrequency.HasValue && customerCoupon.UsedCount >= coupon.SaleRulesEx.CustomerMaxFrequency.Value)
                {
                    SetCouponError(ref order, LanguageHelper.GetText("您已达到使用此优惠券活动的次数上限", order.LanguageCode));
                    continue;
                }
                if (coupon.SaleRulesEx.MaxFrequency.HasValue && totalUsedCount >= coupon.SaleRulesEx.MaxFrequency.Value)
                {
                    SetCouponError(ref order, LanguageHelper.GetText("此优惠券活动已达到全网使用次数上限", order.LanguageCode));
                    continue;
                }


                if (coupon == null)
                {
                    SetCouponError(ref order, LanguageHelper.GetText("此优惠券{0}不存在", order.LanguageCode), merchantCoupon.CouponName);
                    continue;
                }
                #endregion

                #region 3、详细检查该优惠券号码是否可用
                if (!string.IsNullOrWhiteSpace(coupon.SaleRulesEx.NeedEmailVerification) && coupon.SaleRulesEx.NeedEmailVerification.ToUpper().Trim() == "Y")
                {
                    if (order.Customer.IsEmailConfirmed != 1)
                    {
                        SetCouponError(ref order, LanguageHelper.GetText("此优惠券要求客户验证了电子邮箱才可使用!", order.LanguageCode));
                        continue;
                    }
                }
                if (!string.IsNullOrWhiteSpace(coupon.SaleRulesEx.NeedMobileVerification) && coupon.SaleRulesEx.NeedMobileVerification.ToUpper().Trim() == "Y")
                {
                    if (order.Customer.IsPhoneValided != 1)
                    {
                        SetCouponError(ref order, LanguageHelper.GetText("此优惠券要求客户验证了手机才可使用!", order.LanguageCode));
                        continue;
                    }
                }
                if (coupon.SaleRulesList.Count > 0 && coupon.SaleRulesList.Exists(f => f.SaleRuleType == CouponSaleRuleType.RelCustomerRank))
                {
                    //-1表示不限制
                    if (!coupon.SaleRulesList.Exists(f => f.CustomerRank == -1))
                    {
                        int customerRank = order.Customer.CustomerRank;
                        if (!coupon.SaleRulesList.Exists(f => f.CustomerRank == customerRank))
                        {
                            SetCouponError(ref order, LanguageHelper.GetText("当前客户不满足此优惠券要求的客户等级!", order.LanguageCode));
                            continue;
                        }
                    }
                }
                if (coupon.SaleRulesList.Count > 0 && coupon.SaleRulesList.Exists(f => f.SaleRuleType == CouponSaleRuleType.RelArea))
                {
                    int  areaID     = order.Contact.AddressAreaID;
                    Area area       = PromotionDA.GetAreaBySysNo(areaID);
                    int  provinceId = area.ProvinceSysNo.Value;

                    if (!coupon.SaleRulesList.Exists(f => f.SaleRuleType == CouponSaleRuleType.RelArea && f.AreaSysNo == provinceId))
                    {
                        SetCouponError(ref order, LanguageHelper.GetText("当前客户不满足此优惠券要求的客户地区!", order.LanguageCode));
                        continue;
                    }
                }


                #endregion

                #region 4、计算该优惠券可以抵扣多少,填充到OrderInfo中
                if (coupon.DiscountRuleList != null && coupon.DiscountRuleList.Count > 0)
                {
                    //取得满足优惠券条件的商品总金额
                    decimal canCalculateAmount = GetCanCalculateAmount(merchantOrder.Value, coupon);
                    if (canCalculateAmount == 0)
                    {
                        SetCouponError(ref order, LanguageHelper.GetText("没有满足该优惠券的商品,无法抵扣", order.LanguageCode));
                        continue;
                    }

                    canCalculateAmount = canCalculateAmount - Math.Abs(order.TotalDiscountAmount);

                    if (canCalculateAmount < coupon.SaleRulesEx.OrderAmountLimit)
                    {
                        SetCouponError(ref order, LanguageHelper.GetText("没有满足该优惠券要求的商品总金额下限{0},无法抵扣", order.LanguageCode), coupon.SaleRulesEx.OrderAmountLimit);
                        continue;
                    }

                    decimal totalPriceAmount = (merchantOrder.Value.Sum(m => m.TotalProductAmount) - merchantOrder.Value.Sum(m => m.TotalDiscountAmount));

                    #region 处理订单 折扣金额模式 和 百分比模式
                    if (coupon.DiscountRuleList[0].DiscountType == CouponDiscountType.OrderAmountDiscount || coupon.DiscountRuleList[0].DiscountType == CouponDiscountType.OrderAmountPercentage)
                    {
                        //获取适合的折扣规则
                        Coupon_DiscountRules curDiscountRule = GetMatchDiscountRule(coupon, canCalculateAmount);
                        if (curDiscountRule == null)
                        {
                            SetCouponError(ref order, LanguageHelper.GetText("订单总金额未达到优惠券要求的最小购买金额,无法抵扣", order.LanguageCode));
                            return;
                        }

                        decimal discount = 0m;
                        if (curDiscountRule.DiscountType == CouponDiscountType.OrderAmountDiscount)
                        {
                            discount = Math.Abs(Math.Round(curDiscountRule.Value, 2));
                        }
                        else
                        {
                            discount = Math.Abs(Math.Round(canCalculateAmount * curDiscountRule.Value, 2));
                        }



                        if (coupon.SaleRulesEx.OrderMaxDiscount.HasValue && coupon.SaleRulesEx.OrderMaxDiscount.Value > 0m)
                        {
                            if (discount > coupon.SaleRulesEx.OrderMaxDiscount.Value)
                            {
                                discount = coupon.SaleRulesEx.OrderMaxDiscount.Value;
                            }
                        }

                        foreach (var subOrder in merchantOrder.Value)
                        {
                            subOrder.MerchantCouponCodeSysNo = customerCoupon.CouponCodeSysNo;
                            subOrder.MerchantCouponCode      = customerCoupon.CouponCode;
                            subOrder.MerchantCouponSysNo     = customerCoupon.CouponSysNo;
                            subOrder.MerchantCouponName      = customerCoupon.CouponName;
                            subOrder.MerchantCouponAmount    = discount * ((subOrder.TotalProductAmount - subOrder.TotalDiscountAmount) / totalPriceAmount);
                            subOrder.MerchantCouponErrorDesc = string.Empty;
                            foreach (var itemGroup in subOrder.OrderItemGroupList)
                            {
                                foreach (var item in itemGroup.ProductItemList)
                                {
                                    item["UnitCouponAmt"] = (discount * (item.UnitSalePrice - (item["UnitDiscountAmt"] == null ? 0m :(decimal)item["UnitDiscountAmt"])))
                                                            / totalPriceAmount;
                                    item["MerchantUnitCouponAmt"] = (discount * (item.UnitSalePrice - (item["UnitDiscountAmt"] == null ? 0m : (decimal)item["UnitDiscountAmt"])))
                                                                    / totalPriceAmount;
                                }
                            }
                        }
                    }
                    #endregion

                    #region 处理 一个商品直减模式
                    if (coupon.DiscountRuleList[0].DiscountType == CouponDiscountType.ProductPriceDiscount)
                    {
                        if (coupon.SaleRulesList == null || coupon.SaleRulesList.Count == 0)
                        {
                            SetCouponError(ref order, LanguageHelper.GetText("没有满足该优惠券的指定商品,无法抵扣", order.LanguageCode));
                            return;
                        }
                        Coupon_SaleRules productSaleRule = coupon.SaleRulesList.Find(f => f.SaleRuleType == CouponSaleRuleType.RelProduct);


                        int discountProductSysNo = productSaleRule.ProductSysNo;

                        int     discountProductCount = 0;
                        decimal productReduce        = 0m;
                        decimal productPrice         = 0.00m;
                        foreach (OrderItemGroup itemGroup in order.OrderItemGroupList)
                        {
                            OrderProductItem item = itemGroup.ProductItemList.Find(f => f.ProductSysNo == discountProductSysNo);
                            if (item != null)
                            {
                                discountProductCount += item.UnitQuantity * itemGroup.Quantity;

                                productPrice = item.UnitSalePrice;
                            }
                        }
                        if (discountProductCount == 0)
                        {
                            SetCouponError(ref order, LanguageHelper.GetText("没有满足该优惠券的指定商品,无法抵扣", order.LanguageCode));
                            return;
                        }

                        if (discountProductCount > coupon.DiscountRuleList[0].Quantity)
                        {
                            discountProductCount = coupon.DiscountRuleList[0].Quantity;
                        }

                        productReduce = coupon.DiscountRuleList[0].Value;
                        if (coupon.DiscountRuleList[0].Value > productPrice)
                        {
                            productReduce = productPrice;
                        }

                        decimal discount = Math.Abs(Math.Round(productReduce * discountProductCount, 2));



                        if (coupon.SaleRulesEx.OrderMaxDiscount.HasValue && coupon.SaleRulesEx.OrderMaxDiscount.Value > 0m)
                        {
                            if (discount > coupon.SaleRulesEx.OrderMaxDiscount.Value)
                            {
                                discount = coupon.SaleRulesEx.OrderMaxDiscount.Value;
                            }
                        }
                        foreach (var subOrder in merchantOrder.Value)
                        {
                            subOrder.MerchantCouponCodeSysNo = customerCoupon.CouponCodeSysNo;
                            subOrder.MerchantCouponCode      = customerCoupon.CouponCode;
                            subOrder.MerchantCouponSysNo     = customerCoupon.CouponSysNo;
                            subOrder.MerchantCouponName      = customerCoupon.CouponName;
                            subOrder.MerchantCouponAmount    = discount * ((subOrder.TotalProductAmount - subOrder.TotalDiscountAmount) / totalPriceAmount);
                            subOrder.MerchantCouponErrorDesc = string.Empty;

                            subOrder["MerchantCoupon_DiscountProductSysNo"] = discountProductSysNo;
                            subOrder["MerchantCoupon_DiscountProductCount"] = discountProductCount;
                            foreach (var itemGroup in subOrder.OrderItemGroupList)
                            {
                                foreach (var item in itemGroup.ProductItemList)
                                {
                                    item["UnitCouponAmt"] = (discount * (item.UnitSalePrice - (item["UnitDiscountAmt"] == null ? 0m : (decimal)item["UnitDiscountAmt"])))
                                                            / totalPriceAmount;
                                    item["MerchantUnitCouponAmt"] = (discount * (item.UnitSalePrice - (item["UnitDiscountAmt"] == null ? 0m : (decimal)item["UnitDiscountAmt"])))
                                                                    / totalPriceAmount;
                                }
                            }
                        }
                    }
                    #endregion

                    #region 处理 一个商品最终售价模式
                    if (coupon.DiscountRuleList[0].DiscountType == CouponDiscountType.ProductPriceFinal)
                    {
                        if (coupon.SaleRulesList == null || coupon.SaleRulesList.Count == 0)
                        {
                            SetCouponError(ref order, LanguageHelper.GetText("没有满足该优惠券的指定商品,无法抵扣", order.LanguageCode));
                            return;
                        }
                        Coupon_SaleRules productSaleRule = coupon.SaleRulesList.Find(f => f.SaleRuleType == CouponSaleRuleType.RelProduct);


                        int discountProductSysNo = productSaleRule.ProductSysNo;

                        decimal discountProductPrice = 0.00m;
                        int     discountProductCount = 0;
                        foreach (var currOrder in merchantOrder.Value)
                        {
                            foreach (OrderItemGroup itemGroup in currOrder.OrderItemGroupList)
                            {
                                OrderProductItem item = itemGroup.ProductItemList.Find(f => f.ProductSysNo == discountProductSysNo);
                                if (item != null)
                                {
                                    discountProductCount += item.UnitQuantity * itemGroup.Quantity;
                                    discountProductPrice  = item.UnitSalePrice;
                                }
                            }
                        }
                        if (discountProductCount == 0)
                        {
                            SetCouponError(ref order, LanguageHelper.GetText("没有满足该优惠券的指定商品,无法抵扣", order.LanguageCode));
                            return;
                        }
                        if (discountProductCount > coupon.DiscountRuleList[0].Quantity)
                        {
                            discountProductCount = coupon.DiscountRuleList[0].Quantity;
                        }

                        decimal discount = 0m;
                        if (discountProductPrice > coupon.DiscountRuleList[0].Value)
                        {
                            discount = Math.Abs(Math.Round((discountProductPrice - coupon.DiscountRuleList[0].Value) * discountProductCount, 2));
                        }
                        else
                        {
                            SetCouponError(ref order, LanguageHelper.GetText("该优惠券的指定商品已经是优惠券设定的最低价格,无法抵扣", order.LanguageCode));
                            return;
                        }
                        if (coupon.SaleRulesEx.OrderMaxDiscount.HasValue && coupon.SaleRulesEx.OrderMaxDiscount.Value > 0m)
                        {
                            if (discount > coupon.SaleRulesEx.OrderMaxDiscount.Value)
                            {
                                discount = coupon.SaleRulesEx.OrderMaxDiscount.Value;
                            }
                        }
                        foreach (var subOrder in merchantOrder.Value)
                        {
                            subOrder.MerchantCouponCodeSysNo = customerCoupon.CouponCodeSysNo;
                            subOrder.MerchantCouponCode      = customerCoupon.CouponCode;
                            subOrder.MerchantCouponSysNo     = customerCoupon.CouponSysNo;
                            subOrder.MerchantCouponName      = customerCoupon.CouponName;
                            subOrder.MerchantCouponAmount    = discount * ((subOrder.TotalProductAmount - subOrder.TotalDiscountAmount) / totalPriceAmount);
                            subOrder.MerchantCouponErrorDesc = string.Empty;

                            subOrder["MerchantCoupon_DiscountProductSysNo"] = discountProductSysNo;
                            subOrder["MerchantCoupon_DiscountProductCount"] = discountProductCount;
                            foreach (var itemGroup in subOrder.OrderItemGroupList)
                            {
                                foreach (var item in itemGroup.ProductItemList)
                                {
                                    item["UnitCouponAmt"] = (discount * (item.UnitSalePrice - (item["UnitDiscountAmt"] == null ? 0m : (decimal)item["UnitDiscountAmt"])))
                                                            / totalPriceAmount;
                                    item["MerchantUnitCouponAmt"] = (discount * (item.UnitSalePrice - (item["UnitDiscountAmt"] == null ? 0m : (decimal)item["UnitDiscountAmt"])))
                                                                    / totalPriceAmount;
                                }
                            }
                        }
                    }
                    #endregion

                    foreach (var subOrder in merchantOrder.Value)
                    {
                        subOrder["MerchantCoupon_DiscountType"] = coupon.DiscountRuleList[0].DiscountType;
                    }
                }

                #endregion
            }

            #endregion
        }