private void UnlockPromotionIfNecessary(double promotionProgress, double promotionThreshold, PromotionTriggerTypes triggerType, Guid accountId, PromotionDetail promotion) { // Check if promotion needs to be unlocked bool isPromotionUnlocked = false; if (triggerType == PromotionTriggerTypes.RideCount) { isPromotionUnlocked = promotionProgress != 0 && promotionProgress >= promotionThreshold && (promotionProgress % promotionThreshold) == 0; } else if (triggerType == PromotionTriggerTypes.AmountSpent) { isPromotionUnlocked = promotionProgress >= promotionThreshold; } if (isPromotionUnlocked) { _commandBus.Send(new AddUserToPromotionWhiteList { AccountIds = new[] { accountId }, PromoId = promotion.Id, LastTriggeredAmount = promotionProgress }); } }
private void UpdateRideProgression(IEnumerable <PromotionDetail> activePromotions, PromotionTriggerTypes triggerType, Guid accountId, Guid orderId, double?value = null) { if (value == null && triggerType == PromotionTriggerTypes.AmountSpent) { throw new ArgumentNullException("value", "Value parameter should not be null with Amount Spent triggerType"); } using (var context = _contextFactory.Invoke()) { var promotions = activePromotions.Where(p => p.TriggerSettings.Type == triggerType); foreach (var promotion in promotions) { var promoStartDate = promotion.GetStartDateTime(); var promoEndDate = promotion.GetEndDateTime(); // Get all orders from account that are in the date range of the promotion var eligibleOrdersQuery = context.Set <OrderDetail>() .Where( x => x.Status == (int)OrderStatus.Completed && x.AccountId == accountId && x.PickupDate >= promoStartDate); // Check for promotion end date if (promoEndDate.HasValue) { eligibleOrdersQuery = eligibleOrdersQuery.Where(x => x.PickupDate < promoEndDate); } var eligibleOrders = eligibleOrdersQuery.ToArray(); if (promotion.TriggerSettings.Type == PromotionTriggerTypes.RideCount) { var orderCount = eligibleOrders.Any(x => x.Id == orderId) ? eligibleOrders.Length : eligibleOrders.Length + 1; UnlockPromotionIfNecessary(orderCount, promotion.TriggerSettings.RideCount, triggerType, accountId, promotion); } else if (promotion.TriggerSettings.Type == PromotionTriggerTypes.AmountSpent) { var promotionProgressDetail = context.Set <PromotionProgressDetail>().Find(accountId, promotion.Id); double lastTriggeredAmount = 0; if (promotionProgressDetail != null && promotionProgressDetail.LastTriggeredAmount.HasValue) { lastTriggeredAmount = promotionProgressDetail.LastTriggeredAmount.Value; } var totalAmountSpent = eligibleOrders.Any(x => x.Id == orderId) ? eligibleOrders.Sum(x => x.Fare.GetValueOrDefault() + x.Tax.GetValueOrDefault() + x.Toll.GetValueOrDefault() + x.Surcharge.GetValueOrDefault()) : eligibleOrders.Sum(x => x.Fare.GetValueOrDefault() + x.Tax.GetValueOrDefault() + x.Toll.GetValueOrDefault() + x.Surcharge.GetValueOrDefault()) + value; // To get the current progress of the promo, we need to calculate only from the last time the promo was triggered var amountSpentProgress = totalAmountSpent.GetValueOrDefault() - lastTriggeredAmount; UnlockPromotionIfNecessary(amountSpentProgress, promotion.TriggerSettings.AmountSpent, triggerType, accountId, promotion); } } } }