示例#1
0
        protected virtual List <OrderLine> GetOrderLinesInScope(CouponTemplateData couponTemplate, Order order,
                                                                Dictionary <Guid, ProductDto> productDict)
        {
            if (couponTemplate.IsUnscoped)
            {
                return(order.OrderLines);
            }

            var expectedOrderLines = new List <OrderLine>();

            foreach (var scope in couponTemplate.Scopes.Where(scope => scope.StoreId == order.StoreId))
            {
                expectedOrderLines.AddRange(order.OrderLines
                                            .WhereIf(scope.ProductGroupName != null,
                                                     x => productDict[x.ProductId].ProductGroupName == scope.ProductGroupName)
                                            .WhereIf(scope.ProductId.HasValue, x => x.ProductId == scope.ProductId)
                                            .WhereIf(scope.ProductSkuId.HasValue, x => x.ProductSkuId == scope.ProductSkuId));
            }

            if (expectedOrderLines.IsNullOrEmpty())
            {
                throw new OrderDoesNotMeetCouponUsageConditionException();
            }

            if (expectedOrderLines.Sum(x => GetOrderLineProductPrice(x, productDict) * x.Quantity) <
                couponTemplate.ConditionAmount)
            {
                throw new OrderDoesNotMeetCouponUsageConditionException();
            }

            return(expectedOrderLines);
        }
示例#2
0
        protected virtual void DiscountOrderLines(CouponTemplateData couponTemplate, Order order,
                                                  List <OrderLine> orderLinesInScope)
        {
            // Todo: support Custom coupon.
            if (couponTemplate.CouponType == CouponType.Custom)
            {
                throw new NotSupportedException();
            }

            var totalOrderLineActualTotalPrice = orderLinesInScope.Sum(x => x.ActualTotalPrice);

            var totalDiscountedAmount = couponTemplate.CouponType == CouponType.PerMeet
                ? couponTemplate.DiscountAmount *
                                        Math.Floor(totalOrderLineActualTotalPrice / couponTemplate.ConditionAmount)
                : couponTemplate.DiscountAmount;

            if (totalDiscountedAmount > totalOrderLineActualTotalPrice)
            {
                totalDiscountedAmount = totalOrderLineActualTotalPrice;
            }

            var remainingDiscountedAmount = totalDiscountedAmount;

            // Todo: https://github.com/EasyAbp/EShop/issues/104
            const int accuracy = 2;

            foreach (var orderLine in orderLinesInScope)
            {
                var maxDiscountAmount =
                    Math.Round(orderLine.ActualTotalPrice / totalOrderLineActualTotalPrice * totalDiscountedAmount,
                               accuracy, MidpointRounding.ToZero);

                var discountAmount = maxDiscountAmount > orderLine.ActualTotalPrice
                    ? orderLine.ActualTotalPrice
                    : maxDiscountAmount;

                order.AddDiscount(orderLine.Id, discountAmount);

                remainingDiscountedAmount -= discountAmount;
            }

            foreach (var orderLine in orderLinesInScope.OrderByDescending(x => x.ActualTotalPrice))
            {
                if (remainingDiscountedAmount == decimal.Zero)
                {
                    break;
                }

                var discountAmount = remainingDiscountedAmount > orderLine.ActualTotalPrice
                    ? orderLine.ActualTotalPrice
                    : remainingDiscountedAmount;

                order.AddDiscount(orderLine.Id, discountAmount);

                remainingDiscountedAmount -= discountAmount;
            }

            if (remainingDiscountedAmount != decimal.Zero)
            {
                throw new ApplicationException();
            }

            order.SetProperty(CouponsConsts.OrderCouponDiscountAmountPropertyName, totalDiscountedAmount);
        }
示例#3
0
 protected virtual bool IsCurrencyExpected(CouponTemplateData couponTemplate, Order order)
 {
     return(couponTemplate.Currency == order.Currency);
 }