public RewardsResponse Calculate(RewardsRequest requestData) { var response = new RewardsResponse() { CustomerId = requestData.CustomerId, TransactionDate = requestData.TransactionDate, LoyaltyCard = requestData.LoyaltyCard }; var discountedProducts = _discountRepository.GetDiscountedProducts(requestData); var productsRetrieved = _discountRepository.GetProductsInBasket(requestData); var productWithPoints = _pointsPromotionRepository.GetProductPoints(requestData); foreach (var item in productsRetrieved) { var discountpercent = discountedProducts.FirstOrDefault(p => p.ProductId == item.ProductId)?.DiscountPercent ?? 0; var discountedValue = discountpercent * item.UnitPrice * item.Quantity / 100; var originalPrice = item.UnitPrice * item.Quantity; var netPrice = originalPrice - discountedValue; response.DiscountApplied += discountedValue; response.TotalAmount += originalPrice; response.GrandTotal += netPrice; //Promotions repository and Discount reository are clubbed together as the reward points should be calculated on net dollar spent. var PromotionPoints = productWithPoints.FirstOrDefault(p => p.ProductId == item.ProductId)?.PointsPerDollar ?? 0; response.PointsEarned += netPrice * PromotionPoints; } return(response); }
public List <ProductItemDto> GetProductsInBasket(RewardsRequest requestData) { using (var _rewardEntities = new RewardsEntities()) { return(_rewardEntities.Products .Join(requestData.Basket, d => d.ProductId, b => b.ProductId, (d, b) => new ProductItemDto { ProductId = d.ProductId, UnitPrice = d.UnitPrice, Quantity = b.Quantity, }).ToList()); } }
public List <DiscountedProductDto> GetDiscountedProducts(RewardsRequest requestData) { using (var _rewardEntities = new RewardsEntities()) { return(_rewardEntities.DiscountPromotionProducts .Include(i => i.DiscountPromotion) .Include(p => p.Product) .Join(requestData.Basket, d => d.ProductId, b => b.ProductId, (d, b) => new { d.ProductId, d.DiscountPromotion, d.Product, b.Quantity }) .Where(d => d.DiscountPromotion.StartDate <= requestData.TransactionDate && d.DiscountPromotion.EndDate >= requestData.TransactionDate).ToList() .GroupBy(s => s.ProductId). Select(g => new DiscountedProductDto { ProductId = g.Key, DiscountPercent = g.Sum(q => q.DiscountPromotion.DiscountPercent) }).ToList()); } }
public List <PointsPromotionDto> GetProductPoints(RewardsRequest requestData) { using (var _rewardEntities = new RewardsEntities()) { return(_rewardEntities.Products .Join(requestData.Basket, d => d.ProductId, b => b.ProductId, (d, b) => new { d.ProductId, d.UnitPrice, d.Category, b.Quantity }) .Join(_rewardEntities.PointsPromotions, //Doing Cartesian Join and matching category in where clause d => "Any", pr => "Any", (d, pr) => new { d.ProductId, d.Category, PromoCategory = pr.Category, pr.PointsPerDollar, pr.StartDate, pr.EndDate }) .Where(pr => pr.StartDate <= requestData.TransactionDate && pr.EndDate >= requestData.TransactionDate && (pr.Category == pr.PromoCategory || pr.PromoCategory == "Any")) .Select(res => new PointsPromotionDto { ProductId = res.ProductId, PointsPerDollar = res.PointsPerDollar }) .ToList()); } }
private static SaveRewardResponse SaveRewardTrx(RewardsRequest item, ICollector <string> errormessage, TraceWriter log) { SaveRewardResponse saveRewardResponse = new SaveRewardResponse(); saveRewardResponse.RewardTrxID = 0; try { using (var connection = MSSQLConnection.CreateConnection()) { connection.Open(); // Call stored procedure to Save Customer Customer Customers = new Customer(); GetRewardsRequest SaveRewardTrx = new GetRewardsRequest(); if (item.IsValid) { RewardTrxStatus = RewardTrxStatusEnum.ReadyForFulfillmentImmediate.GetDescription(); } if (string.IsNullOrEmpty(item.Customer.SourceSystemUniqueIDType)) { RewardTrxStatus = "Validation error"; item.ValidationMessage += " Source system is not supported."; } if (item.Reward != null && !string.IsNullOrEmpty(item.Reward.ProductValue) && !Decimal.TryParse(item.Reward.ProductValue, out ProductValue)) { RewardTrxStatus = "Validation error"; item.ValidationMessage += " Required numeric value for ProductValue field."; } if (!string.IsNullOrEmpty(item.Customer.SourceSystemID)) { int.TryParse(item.Customer.SourceSystemID, out SourceSystemID); if (SourceSystemID <= 0) { item.IsValid = false; RewardTrxStatus = RewardTrxStatusEnum.ValidationError.GetDescription(); item.ValidationMessage += "Validation Failed : SourceSystemID must be numeric;"; } } if (SourceSystemID > 0 || !string.IsNullOrEmpty(item.Customer.SourceSystemName)) { List <SqlParameter> SSIDprm = new List <SqlParameter>(); SSIDprm.Add(new SqlParameter("@SourceSystemShortName", item.Customer.SourceSystemName)); SSIDprm.Add(new SqlParameter("@SourceSystemID", item.Customer.SourceSystemID)); SourceSystemID = MSSQLConnection.ExecuteStoredProcedure <int>(USPContstants.GetSourceSystemID, SSIDprm).FirstOrDefault(); if (SourceSystemID == 0) { item.IsValid = false; RewardTrxStatus = RewardTrxStatusEnum.ValidationError.GetDescription(); item.ValidationMessage += "Validation Failed : Please provide valid SourceSystemID or SourceSystemName (if both are provided they must match);"; } } else if (item.IsOrder == false) { item.IsValid = false; RewardTrxStatus = RewardTrxStatusEnum.ValidationError.GetDescription(); item.ValidationMessage += "Validation Failed : Required value for at least one of 'SourceSystemID' or 'SourceSystemName'. Path: SourceSystemID or SourceSystemName;"; } item.ValidationMessage = item.ValidationMessage.TrimStart(';'); DynamicParameters CustomerTrxParams = new DynamicParameters(); CustomerTrxParams.Add("@SourceSystemID", SourceSystemID.ToString()); CustomerTrxParams.Add("@SourceSystemUniqueID", item.Customer.SourceSystemUniqueID); CustomerTrxParams.Add("@SourceSystemUniqueIDType", item.Customer.SourceSystemUniqueIDType); CustomerTrxParams.Add("@MasterID", item.Customer.MasterID); CustomerTrxParams.Add("@Email", item.Customer.Email); CustomerTrxParams.Add("@FirstName", item.Customer.FirstName); CustomerTrxParams.Add("@LastName", item.Customer.LastName); CustomerTrxParams.Add("@CompanyName", item.Customer.CompanyName); CustomerTrxParams.Add("@AddressLine1", item.Customer.AddressLine1); CustomerTrxParams.Add("@AddressLine2", item.Customer.AddressLine2); CustomerTrxParams.Add("@City", item.Customer.City); CustomerTrxParams.Add("@StateProvince", item.Customer.StateProvince); CustomerTrxParams.Add("@ZipPostalCode", item.Customer.ZipPostalCode); CustomerTrxParams.Add("@Phone1", item.Customer.Phone1); CustomerTrxParams.Add("@Product", item.Customer.Product); CustomerTrxParams.Add("@Language", item.Customer.Language); CustomerTrxParams.Add("@RequestID", item.RequestId); CustomerTrxParams.Add("@TransactionType", item.TransactionType); CustomerTrxParams.Add("@ProductCode", (item.Reward != null && !string.IsNullOrEmpty(item.Reward.ProductCode)) ? item.Reward.ProductCode : string.Empty); CustomerTrxParams.Add("@ProductValue", ProductValue); CustomerTrxParams.Add("@ProgramName", (item.Reward != null && !string.IsNullOrEmpty(item.Reward.ProgramName)) ? item.Reward.ProgramName : string.Empty); if (item.Reward != null) { CustomerTrxParams.Add("@EffectiveDate", item.Reward.EffectiveDate); } else { CustomerTrxParams.Add("@EffectiveDate", string.Empty); } CustomerTrxParams.Add("@SourceIP", item.SourceIP); CustomerTrxParams.Add("@RewardsRequestReceiveTimestamp", item.RewardsRequestReceiveTimestamp); CustomerTrxParams.Add("@RMSRewardID", item.RMSRewardID); var additionalDataJSON = JsonConvert.SerializeObject(item.AdditionalData); CustomerTrxParams.Add("@AdditionalData", additionalDataJSON); CustomerTrxParams.Add("@RewardType", (!string.IsNullOrEmpty(item.Reward.RewardType)) ? item.Reward.RewardType : string.Empty); CustomerTrxParams.Add("@MessageType", MessageType.RewardRequest.GetDescription()); CustomerTrxParams.Add("@Message", Message); CustomerTrxParams.Add("@RewardTrxStatus", RewardTrxStatus); CustomerTrxParams.Add("@Comment", item.ValidationMessage); SaveRewardTrx = connection.Query <GetRewardsRequest>(Common.Constants.USPContstants.SaveRewards, CustomerTrxParams, null, true, null, CommandType.StoredProcedure).FirstOrDefault(); log.Verbose($"SaveRewardTrx sucessfully ={SaveRewardTrx.RewardTrxID}", "JE.RMS.Services.SaveRewardsTrx"); saveRewardResponse.Status = SaveRewardTrx.RewardTrxStatus; saveRewardResponse.RewardTrxID = SaveRewardTrx.RewardTrxID; saveRewardResponse.IsValid = item.IsValid; //Hack : SP returns validation message in Reward type field (this is internal) saveRewardResponse.ValidationMessage = item.ValidationMessage + SaveRewardTrx.RewardType; } return(saveRewardResponse); } catch (Exception ex) { log.Error($"Exception={ex}", ex, "JE.RMS.Services.ApplyReward"); errormessage.Add(JsonConvert.SerializeObject(ex).ToString()); saveRewardResponse.IsValid = false; saveRewardResponse.ValidationMessage = ex.Message; saveRewardResponse.Status = RewardTrxStatusEnum.Error.GetDescription(); return(saveRewardResponse); } }
public ActionResult Post([FromBody] RewardsRequest request) { var response = _discountService.Calculate(request); return(Ok(response)); }