private void PrepareProductReviewModel(ProductReviewModel model,
            ProductReview productReview, bool excludeProperties, bool formatReviewText)
        {
            if (model == null)
                throw new ArgumentNullException("model");

            if (productReview == null)
                throw new ArgumentNullException("productReview");

            model.Id = productReview.Id;
            model.ProductId = productReview.ProductId;
            model.ProductName = productReview.Product.Name;
			model.ProductTypeName = productReview.Product.GetProductTypeLabel(_localizationService);
			model.ProductTypeLabelHint = productReview.Product.ProductTypeLabelHint;
            model.CustomerId = productReview.CustomerId;
            model.IpAddress = productReview.IpAddress;
            model.Rating = productReview.Rating;
            model.CreatedOn = _dateTimeHelper.ConvertToUserTime(productReview.CreatedOnUtc, DateTimeKind.Utc);
            if (!excludeProperties)
            {
                model.Title = productReview.Title;
                if (formatReviewText)
                    model.ReviewText = Core.Html.HtmlUtils.FormatText(productReview.ReviewText, false, true, false, false, false, false);
                else
                    model.ReviewText = productReview.ReviewText;
                model.IsApproved = productReview.IsApproved;
            }
        }
        public virtual void AddProductReviewTokens(IList<Token> tokens, ProductReview productReview)
        {
            tokens.Add(new Token("ProductReview.ProductName", productReview.Product.Name));

            //event notification
            _eventPublisher.EntityTokensAdded(productReview, tokens);
        }
		public ActionResult ReviewsAdd(int id, ProductReviewsModel model, bool captchaValid)
		{
			var product = _productService.GetProductById(id);
			if (product == null || product.Deleted || !product.Published || !product.AllowCustomerReviews)
				return HttpNotFound();

			//validate CAPTCHA
			if (_captchaSettings.Enabled && _captchaSettings.ShowOnProductReviewPage && !captchaValid)
			{
				ModelState.AddModelError("", T("Common.WrongCaptcha"));
			}

			if (_services.WorkContext.CurrentCustomer.IsGuest() && !_catalogSettings.AllowAnonymousUsersToReviewProduct)
			{
				ModelState.AddModelError("", T("Reviews.OnlyRegisteredUsersCanWriteReviews"));
			}

			if (ModelState.IsValid)
			{
				//save review
				int rating = model.AddProductReview.Rating;
				if (rating < 1 || rating > 5)
					rating = _catalogSettings.DefaultProductRatingValue;

				bool isApproved = !_catalogSettings.ProductReviewsMustBeApproved;
				var customer = _services.WorkContext.CurrentCustomer;

				var productReview = new ProductReview()
				{
					ProductId = product.Id,
					CustomerId = customer.Id,
					IpAddress = _services.WebHelper.GetCurrentIpAddress(),
					Title = model.AddProductReview.Title,
					ReviewText = model.AddProductReview.ReviewText,
					Rating = rating,
					HelpfulYesTotal = 0,
					HelpfulNoTotal = 0,
					IsApproved = isApproved,
					CreatedOnUtc = DateTime.UtcNow,
					UpdatedOnUtc = DateTime.UtcNow,
				};
				_customerContentService.InsertCustomerContent(productReview);

				//update product totals
				_productService.UpdateProductReviewTotals(product);

				//notify store owner
				if (_catalogSettings.NotifyStoreOwnerAboutNewProductReviews)
					_workflowMessageService.SendProductReviewNotificationMessage(productReview, _localizationSettings.DefaultAdminLanguageId);

				//activity log
				_services.CustomerActivity.InsertActivity("PublicStore.AddProductReview", T("ActivityLog.PublicStore.AddProductReview"), product.Name);

				if (isApproved)
					_customerService.RewardPointsForProductReview(customer, product, true);

				_helper.PrepareProductReviewsModel(model, product);
				model.AddProductReview.Title = null;
				model.AddProductReview.ReviewText = null;

				model.AddProductReview.SuccessfullyAdded = true;
				if (!isApproved)
					model.AddProductReview.Result = T("Reviews.SeeAfterApproving");
				else
					model.AddProductReview.Result = T("Reviews.SuccessfullyAdded");

				return View(model);
			}

			//If we got this far, something failed, redisplay form
			_helper.PrepareProductReviewsModel(model, product);
			return View(model);
		}
        /// <summary>
        /// Sends a product review notification message to a store owner
        /// </summary>
        /// <param name="productReview">Product review</param>
        /// <param name="languageId">Message language identifier</param>
        /// <returns>Queued email identifier</returns>
        public virtual int SendProductReviewNotificationMessage(ProductReview productReview,
            int languageId)
        {
            if (productReview == null)
                throw new ArgumentNullException("productReview");

			var store = _storeContext.CurrentStore;
			languageId = EnsureLanguageIsActive(languageId, store.Id);

			var messageTemplate = GetLocalizedActiveMessageTemplate("Product.ProductReview", languageId, store.Id);
			if (messageTemplate == null)
                return 0;

			//tokens
			var tokens = new List<Token>();
			_messageTokenProvider.AddStoreTokens(tokens, store);
			_messageTokenProvider.AddProductReviewTokens(tokens, productReview);

            //event notification
            _eventPublisher.MessageTokensAdded(messageTemplate, tokens);

            var emailAccount = GetEmailAccountOfMessageTemplate(messageTemplate, languageId);
            var toEmail = emailAccount.Email;
            var toName = emailAccount.DisplayName;

            // use customer email as reply address
			var replyTo = GetReplyToEmail(productReview.Customer);

            return SendNotification(messageTemplate, emailAccount,
                languageId, tokens,
                toEmail, toName,
				replyTo.Item1, replyTo.Item2);
        }
        public void Can_get_customer_content_by_type()
        {
            var customer = SaveAndLoadEntity<Customer>(GetTestCustomer(), false);
            var product = SaveAndLoadEntity<Product>(GetTestProduct(), false);

            var productReview = new ProductReview
            {
                Customer = customer,
                Product = product,
                Title = "Test",
                ReviewText = "A review",
                IpAddress = "192.168.1.1",
                IsApproved = true,
                CreatedOnUtc = new DateTime(2010, 01, 01),
                UpdatedOnUtc = new DateTime(2010, 01, 02),
            };
            
            var productReviewHelpfulness = new ProductReviewHelpfulness
            {
                Customer = customer,
                ProductReview = productReview,
                WasHelpful = true,
                IpAddress = "192.168.1.1",
                IsApproved = true,
                CreatedOnUtc = new DateTime(2010, 01, 03),
                UpdatedOnUtc = new DateTime(2010, 01, 04)
            };

            var blogComment = new BlogComment
            {
                Customer = customer,
                IpAddress = "192.168.1.1",
                IsApproved = true,
                CreatedOnUtc = new DateTime(2010, 01, 03),
                UpdatedOnUtc = new DateTime(2010, 01, 04),
                BlogPost = new BlogPost()
                {
                    Title = "Title 1",
                    Body = "Body 1",
                    AllowComments = true,
                    CreatedOnUtc = new DateTime(2010, 01, 01),
                    Language = new Language()
                    {
                        Name = "English",
                        LanguageCulture = "en-Us",
                    }
                }
            };

			var table = context.Set<CustomerContent>();
			table.RemoveRange(table.ToList());

            table.Add(productReview);
            table.Add(productReviewHelpfulness);
            table.Add(blogComment);

            context.SaveChanges();

            context.Dispose();
            context = new SmartObjectContext(GetTestDbName());

            var query = context.Set<CustomerContent>();
			query.ToList().Count.ShouldEqual(3);

            var dbReviews = query.OfType<ProductReview>().ToList();
            dbReviews.Count().ShouldEqual(1);
            dbReviews.First().ReviewText.ShouldEqual("A review");

            var dbHelpfulnessRecords = query.OfType<ProductReviewHelpfulness>().ToList();
            dbHelpfulnessRecords.Count().ShouldEqual(1);
            dbHelpfulnessRecords.First().WasHelpful.ShouldEqual(true);

            var dbBlogCommentRecords = query.OfType<BlogComment>().ToList();
            dbBlogCommentRecords.Count().ShouldEqual(1);
        }
        public void Can_save_productReview_with_helpfulness()
        {
            var customer = SaveAndLoadEntity<Customer>(GetTestCustomer(), false);
            var product = SaveAndLoadEntity<Product>(GetTestProduct(), false);

            var productReview = new ProductReview
            {
                Customer = customer,
                Product = product,
                Title = "Test",
                ReviewText = "A review",
                IpAddress = "192.168.1.1",
                IsApproved = true,
                CreatedOnUtc = new DateTime(2010, 01, 01),
                UpdatedOnUtc = new DateTime(2010, 01, 02)
            };
            productReview.ProductReviewHelpfulnessEntries.Add
                (
                    new ProductReviewHelpfulness
                    {
                        Customer = customer,
                        WasHelpful = true,
                        IpAddress = "192.168.1.1",
                        IsApproved = true,
                        CreatedOnUtc = new DateTime(2010, 01, 03),
                        UpdatedOnUtc = new DateTime(2010, 01, 04)
                    } 
                );
            var fromDb = SaveAndLoadEntity(productReview);
            fromDb.ShouldNotBeNull();
            fromDb.ReviewText.ShouldEqual("A review");


            fromDb.ProductReviewHelpfulnessEntries.ShouldNotBeNull();
            (fromDb.ProductReviewHelpfulnessEntries.Count == 1).ShouldBeTrue();
            fromDb.ProductReviewHelpfulnessEntries.First().WasHelpful.ShouldEqual(true);
        }