public async Task <Review> EditReview(Review review)
        {
            ReviewsResponseWrapper wrapper = await _productReviewRepository.GetProductReviewsMD($"id={review.Id}", null, null);

            Review oldReview = wrapper.Reviews.FirstOrDefault();

            review.Approved          = review.Approved ?? oldReview.Approved;
            review.Location          = string.IsNullOrEmpty(review.Location) ? oldReview.Location : review.Location;
            review.ProductId         = string.IsNullOrEmpty(review.ProductId) ? oldReview.ProductId : review.ProductId;
            review.Rating            = review.Rating ?? oldReview.Rating;
            review.ReviewDateTime    = string.IsNullOrEmpty(review.ReviewDateTime) ? oldReview.ReviewDateTime : review.ReviewDateTime;
            review.ReviewerName      = string.IsNullOrEmpty(review.ReviewerName) ? oldReview.ReviewerName : review.ReviewerName;
            review.ShopperId         = string.IsNullOrEmpty(review.ShopperId) ? oldReview.ShopperId : review.ShopperId;
            review.Sku               = string.IsNullOrEmpty(review.Sku) ? oldReview.Sku : review.Sku;
            review.Text              = string.IsNullOrEmpty(review.Text) ? oldReview.Text : review.Text;
            review.Title             = string.IsNullOrEmpty(review.Title) ? oldReview.Title : review.Title;
            review.Locale            = string.IsNullOrEmpty(review.Locale) ? oldReview.Locale : review.Locale;
            review.VerifiedPurchaser = review.VerifiedPurchaser ?? oldReview.VerifiedPurchaser;

            string id = await this._productReviewRepository.SaveProductReviewMD(review);

            if (string.IsNullOrEmpty(id))
            {
                review = null;
            }
            else
            {
                review.Id = id;
            }

            return(review);
        }
        public async Task <bool> ModerateReview(string[] ids, bool approved)
        {
            bool retval = true;
            IDictionary <int, string> lookup = await _productReviewRepository.LoadLookupAsync();

            foreach (string id in ids)
            {
                ReviewsResponseWrapper wrapper = await this._productReviewRepository.GetProductReviewsMD($"id={id}", null, null);

                Review reviewToModerate = wrapper.Reviews.Where(r => r.Id == id).FirstOrDefault();
                if (reviewToModerate != null)
                {
                    reviewToModerate.Approved = approved;
                    string returnedId = await this._productReviewRepository.SaveProductReviewMD(reviewToModerate);

                    if (string.IsNullOrEmpty(returnedId))
                    {
                        retval = false;
                    }
                }
                else
                {
                    retval = false;
                }
            }

            return(retval);
        }
        public async Task <decimal> GetAverageRatingByProductId(string productId)
        {
            string      searchQuery   = $"productId={productId}";
            decimal     averageRating = 0m;
            AppSettings settings      = await GetAppSettings();

            if (settings.RequireApproval)
            {
                searchQuery = $"{searchQuery}&approved=true";
            }

            ReviewsResponseWrapper wrapper = await this._productReviewRepository.GetProductReviewsMD(searchQuery, null, null);

            IList <Review> reviews = wrapper.Reviews;

            if (reviews != null)
            {
                int numberOfReviews = reviews.Count;
                if (numberOfReviews > 0)
                {
                    decimal totalRating = reviews.Sum(r => r.Rating ?? 0);
                    averageRating = totalRating / numberOfReviews;
                }
            }

            return(decimal.Round(averageRating, 2, MidpointRounding.AwayFromZero));
        }
        public async Task <Review> GetReview(string Id)
        {
            Review review = null;
            ReviewsResponseWrapper wrapper = await this._productReviewRepository.GetProductReviewsMD($"id={Id}", null, null);

            IList <Review> reviews = wrapper.Reviews;

            if (reviews != null)
            {
                review = reviews.FirstOrDefault();
            }

            return(review);
        }
        public async Task <bool> HasShopperReviewed(string shopperId, string productId)
        {
            bool retval = false;

            try
            {
                ReviewsResponseWrapper wrapper = await this._productReviewRepository.GetProductReviewsMD($"shopperId={shopperId}&productId={productId}", null, null);

                IList <Review> reviews = wrapper.Reviews;
                if (reviews != null && reviews.Count > 0)
                {
                    retval = true;
                }
            }
            catch (Exception ex)
            {
                _context.Vtex.Logger.Error("HasShopperReviewed", null, "Request Error", ex);
            }

            return(retval);
        }
        /// query Reviews($searchTerm: String, $from: Int, $to: Int, $orderBy: String, $status: Boolean)
        public async Task <ReviewsResponseWrapper> GetReviews(string searchTerm, int from, int to, string orderBy, string status)
        {
            string searchQuery = string.Empty;
            string statusQuery = string.Empty;

            if (!string.IsNullOrEmpty(searchTerm))
            {
                searchQuery = $"&_keyword={searchTerm}";
            }

            if (!string.IsNullOrEmpty(status))
            {
                statusQuery = $"&approved={status}";
            }

            string sortQuery = await this.GetSortQuery(orderBy);

            ReviewsResponseWrapper wrapper = await _productReviewRepository.GetProductReviewsMD($"{searchQuery}{sortQuery}{statusQuery}", Convert.ToString(from), Convert.ToString(to));

            return(wrapper);
        }
        public async Task <ReviewsResponseWrapper> GetRangeReviewsMD(string fromDate, string toDate)
        {
            await this.VerifySchema();

            ReviewsResponseWrapper reviewsResponse = null;
            IList <Review>         reviews         = new List <Review>();
            DateTime dtFromDate = DateTime.Parse(fromDate);

            fromDate = dtFromDate.ToString("yyyy-MM-ddTHH:mm:ssZ");
            DateTime dtToDate = DateTime.Parse(toDate);

            toDate = dtToDate.ToString("yyyy-MM-ddTHH:mm:ssZ");
            string total        = "0";
            string responseFrom = "0";
            string responseTo   = "0";

            fromDate = HttpUtility.UrlEncode(fromDate);
            toDate   = HttpUtility.UrlEncode(toDate);

            var request = new HttpRequestMessage
            {
                Method     = HttpMethod.Get,
                RequestUri = new Uri($"http://{this._httpContextAccessor.HttpContext.Request.Headers[VTEX_ACCOUNT_HEADER_NAME]}.vtexcommercestable.com.br/api/dataentities/{DATA_ENTITY}/search?_fields=_all&_schema={SCHEMA}&_where=searchDate between {fromDate} AND {toDate}")
            };

            request.Headers.Add("REST-Range", $"resources={0}-{800}");

            string authToken = this._httpContextAccessor.HttpContext.Request.Headers[HEADER_VTEX_CREDENTIAL];

            if (authToken != null)
            {
                request.Headers.Add(AUTHORIZATION_HEADER_NAME, authToken);
                request.Headers.Add(VTEX_ID_HEADER_NAME, authToken);
                request.Headers.Add(PROXY_AUTHORIZATION_HEADER_NAME, authToken);
            }

            var client   = _clientFactory.CreateClient();
            var response = await client.SendAsync(request);

            string responseContent = await response.Content.ReadAsStringAsync();

            if (response.IsSuccessStatusCode)
            {
                reviews = JsonConvert.DeserializeObject <IList <Review> >(responseContent);
            }

            HttpHeaders          headers = response.Headers;
            IEnumerable <string> values;

            if (headers.TryGetValues("REST-Content-Range", out values))
            {
                // resources 0-10/168
                string   resources   = values.First();
                string[] split       = resources.Split(' ');
                string   ranges      = split[1];
                string[] splitRanges = ranges.Split('/');
                string   fromTo      = splitRanges[0];
                total = splitRanges[1];
                string[] splitFromTo = fromTo.Split('-');
                responseFrom = splitFromTo[0];
                responseTo   = splitFromTo[1];
            }

            reviewsResponse = new ReviewsResponseWrapper
            {
                Reviews = reviews,
                Range   = new SearchRange
                {
                    From  = long.Parse(responseFrom),
                    To    = long.Parse(responseTo),
                    Total = long.Parse(total)
                }
            };

            return(reviewsResponse);
        }
        public async Task <ReviewsResponseWrapper> GetProductReviewsMD(string searchQuery, string from, string to)
        {
            await this.VerifySchema();

            ReviewsResponseWrapper reviewsResponse = null;
            IList <Review>         reviews         = null;
            string total        = string.Empty;
            string responseFrom = string.Empty;
            string responseTo   = string.Empty;

            if (string.IsNullOrEmpty(from))
            {
                from = "0";
            }
            if (string.IsNullOrEmpty(to))
            {
                to = "300";
            }
            if (!string.IsNullOrEmpty(searchQuery))
            {
                if (!searchQuery.First().Equals('&'))
                {
                    searchQuery = $"&{searchQuery}";
                }
            }

            var request = new HttpRequestMessage
            {
                Method     = HttpMethod.Get,
                RequestUri = new Uri($"http://{this._httpContextAccessor.HttpContext.Request.Headers[VTEX_ACCOUNT_HEADER_NAME]}.vtexcommercestable.com.br/api/dataentities/{DATA_ENTITY}/search?_fields=_all&_schema={SCHEMA}{searchQuery}")
            };

            request.Headers.Add("REST-Range", $"resources={from}-{to}");

            string authToken = this._httpContextAccessor.HttpContext.Request.Headers[HEADER_VTEX_CREDENTIAL];

            if (authToken != null)
            {
                request.Headers.Add(AUTHORIZATION_HEADER_NAME, authToken);
                request.Headers.Add(VTEX_ID_HEADER_NAME, authToken);
                request.Headers.Add(PROXY_AUTHORIZATION_HEADER_NAME, authToken);
            }

            var client   = _clientFactory.CreateClient();
            var response = await client.SendAsync(request);

            string responseContent = await response.Content.ReadAsStringAsync();

            if (response.IsSuccessStatusCode)
            {
                reviews = JsonConvert.DeserializeObject <IList <Review> >(responseContent);
            }

            HttpHeaders          headers = response.Headers;
            IEnumerable <string> values;

            if (headers.TryGetValues("REST-Content-Range", out values))
            {
                // resources 0-10/168
                string   resources   = values.First();
                string[] split       = resources.Split(' ');
                string   ranges      = split[1];
                string[] splitRanges = ranges.Split('/');
                string   fromTo      = splitRanges[0];
                total = splitRanges[1];
                string[] splitFromTo = fromTo.Split('-');
                responseFrom = splitFromTo[0];
                responseTo   = splitFromTo[1];
            }

            reviewsResponse = new ReviewsResponseWrapper
            {
                Reviews = reviews,
                Range   = new SearchRange
                {
                    From  = long.Parse(responseFrom),
                    To    = long.Parse(responseTo),
                    Total = long.Parse(total)
                }
            };

            return(reviewsResponse);
        }
        public async Task <ReviewsResponseWrapper> GetReviewsByDateRange(string fromDate, string toDate)
        {
            ReviewsResponseWrapper wrapper = await _productReviewRepository.GetRangeReviewsMD(fromDate, toDate);

            return(wrapper);
        }
        public async Task <ReviewsResponseWrapper> GetReviewsByreviewDateTime(string reviewDateTime)
        {
            ReviewsResponseWrapper wrapper = await _productReviewRepository.GetProductReviewsMD($"reviewDateTime={reviewDateTime}", null, null);

            return(wrapper);
        }
        public async Task <ReviewsResponseWrapper> GetReviewsByShopperId(string shopperId)
        {
            ReviewsResponseWrapper wrapper = await _productReviewRepository.GetProductReviewsMD($"shopperId={shopperId}", null, null);

            return(wrapper);
        }
Example #12
0
        public async Task <IActionResult> ProcessReviewApiAction(string requestedAction, string id)
        {
            await this.VerifySchema();

            Response.Headers.Add("Cache-Control", "public, max-age=300, stale-while-revalidate=3600, stale-if-error=3600");
            string        responseString   = string.Empty;
            string        vtexCookie       = HttpContext.Request.Headers[HEADER_VTEX_COOKIE];
            ValidatedUser validatedUser    = null;
            bool          userValidated    = false;
            bool          keyAndTokenValid = false;
            string        vtexAppKey       = HttpContext.Request.Headers[HEADER_VTEX_APP_KEY];
            string        vtexAppToken     = HttpContext.Request.Headers[HEADER_VTEX_APP_TOKEN];

            if (!string.IsNullOrEmpty(vtexCookie))
            {
                validatedUser = await this._productReviewsService.ValidateUserToken(vtexCookie);

                if (validatedUser != null)
                {
                    if (validatedUser.AuthStatus.Equals(AUTH_SUCCESS))
                    {
                        userValidated = true;
                    }
                }
            }

            if (!string.IsNullOrEmpty(vtexAppKey) && !string.IsNullOrEmpty(vtexAppToken))
            {
                string baseUrl = HttpContext.Request.Headers[FORWARDED_HOST];
                keyAndTokenValid = await this._productReviewsService.ValidateKeyAndToken(vtexAppKey, vtexAppToken, baseUrl);
            }

            if (string.IsNullOrEmpty(requestedAction))
            {
                return(BadRequest("Missing parameter"));
            }

            if ("post".Equals(HttpContext.Request.Method, StringComparison.OrdinalIgnoreCase))
            {
                string bodyAsText = await new System.IO.StreamReader(HttpContext.Request.Body).ReadToEndAsync();
                switch (requestedAction)
                {
                case REVIEW:
                    if (!userValidated)
                    {
                        return(Unauthorized("Invalid User"));
                    }

                    Review newReview          = JsonConvert.DeserializeObject <Review>(bodyAsText);
                    bool   hasShopperReviewed = await _productReviewsService.HasShopperReviewed(validatedUser.User, newReview.ProductId);

                    if (hasShopperReviewed)
                    {
                        return(Json("Duplicate Review"));
                    }

                    bool hasShopperPurchased = await _productReviewsService.ShopperHasPurchasedProduct(validatedUser.User, newReview.ProductId);

                    Review reviewToSave = new Review
                    {
                        ProductId         = newReview.ProductId,
                        Rating            = newReview.Rating,
                        ShopperId         = validatedUser.User,
                        Title             = newReview.Title,
                        Text              = newReview.Text,
                        ReviewerName      = newReview.ReviewerName,
                        ReviewDateTime    = newReview.ReviewDateTime,
                        VerifiedPurchaser = hasShopperPurchased
                    };

                    var reviewResponse = await this._productReviewsService.NewReview(reviewToSave, false);

                    return(Json(reviewResponse.Id));

                    break;

                case REVIEWS:
                    if (!keyAndTokenValid)
                    {
                        return(Unauthorized());
                    }

                    IList <Review> reviews = JsonConvert.DeserializeObject <IList <Review> >(bodyAsText);
                    List <string>  ids     = new List <string>();
                    foreach (Review review in reviews)
                    {
                        var reviewsResponse = await this._productReviewsService.NewReview(review, false);

                        ids.Add(reviewsResponse.Id);
                    }

                    return(Json(ids));

                    break;
                }
            }
            else if ("delete".Equals(HttpContext.Request.Method, StringComparison.OrdinalIgnoreCase))
            {
                string[] ids;
                switch (requestedAction)
                {
                case REVIEW:
                    if (!userValidated && !keyAndTokenValid)
                    {
                        return(Json("Invalid User"));
                    }

                    if (string.IsNullOrEmpty(id))
                    {
                        return(BadRequest("Missing parameter."));
                    }

                    ids    = new string[1];
                    ids[0] = id;
                    return(Json(await this._productReviewsService.DeleteReview(ids)));

                    break;

                case REVIEWS:
                    if (!keyAndTokenValid)
                    {
                        return(Unauthorized());
                    }

                    string bodyAsText = await new System.IO.StreamReader(HttpContext.Request.Body).ReadToEndAsync();
                    ids = JsonConvert.DeserializeObject <string[]>(bodyAsText);
                    return(Json(await this._productReviewsService.DeleteReview(ids)));

                    break;
                }
            }
            else if ("patch".Equals(HttpContext.Request.Method, StringComparison.OrdinalIgnoreCase))
            {
                switch (requestedAction)
                {
                case REVIEW:
                    if (!userValidated && !keyAndTokenValid)
                    {
                        return(Json("Invalid User"));
                    }

                    string bodyAsText = await new System.IO.StreamReader(HttpContext.Request.Body).ReadToEndAsync();
                    Review review     = JsonConvert.DeserializeObject <Review>(bodyAsText);
                    review.Id = id;
                    return(Json(await this._productReviewsService.EditReview(review)));

                    break;
                }
            }
            else if ("get".Equals(HttpContext.Request.Method, StringComparison.OrdinalIgnoreCase))
            {
                ReviewsResponseWrapper wrapper = null;
                var    queryString             = HttpContext.Request.Query;
                var    searchTerm  = queryString["search_term"];
                var    fromParam   = queryString["from"];
                var    toParam     = queryString["to"];
                var    orderBy     = queryString["order_by"];
                var    status      = queryString["status"];
                var    productId   = queryString["product_id"];
                int    rating      = 0;
                string ratingQS    = queryString["rating"];
                var    locale      = queryString["locale"];
                var    boolValue   = queryString["pastReviews"];
                bool   pastReviews = false;
                bool.TryParse(boolValue, out pastReviews);
                switch (requestedAction)
                {
                case REVIEW:
                    if (string.IsNullOrEmpty(id))
                    {
                        return(BadRequest("Missing parameter."));
                    }

                    Review review = await this._productReviewsService.GetReview(id);

                    return(Json(review));

                    break;

                case REVIEWS:
                    IList <Review> reviews;
                    if (!string.IsNullOrEmpty(ratingQS))
                    {
                        int.TryParse(ratingQS, out rating);
                    }

                    if (string.IsNullOrEmpty(fromParam))
                    {
                        fromParam = "0";
                    }

                    if (string.IsNullOrEmpty(toParam))
                    {
                        toParam = "3";
                    }

                    int from = int.Parse(fromParam);
                    int to   = int.Parse(toParam);

                    if (!string.IsNullOrEmpty(productId))
                    {
                        wrapper = await _productReviewsService.GetReviewsByProductId(productId, from, to, orderBy, searchTerm, rating, locale, pastReviews);
                    }
                    else
                    {
                        wrapper = await _productReviewsService.GetReviews(searchTerm, from, to, orderBy, status);
                    }

                    SearchResponse searchResponse = new SearchResponse
                    {
                        Data = new DataElement {
                            data = wrapper.Reviews
                        },
                        Range = wrapper.Range
                    };

                    return(Json(searchResponse));

                    break;

                case RATING:
                    decimal average = await _productReviewsService.GetAverageRatingByProductId(id);

                    wrapper = await _productReviewsService.GetReviewsByProductId(id);

                    RatingResponse ratingResponse = new RatingResponse
                    {
                        Average    = average,
                        TotalCount = wrapper.Range.Total
                    };

                    return(Json(ratingResponse));
                }
            }

            return(Json(responseString));
        }