Ejemplo n.º 1
0
        public ActionResult SaveRecipe(PostedRecipeViewModel postedRecipeViewModel)
        {
            // NOTE: This action handles saving for both new recipes
            // and edited recipes.  New Recipes post to this action while
            // edits post to this action via Ajax.

            var isNewRecipe = false;

            // Hydrate JSON ReceipeViewModel
            var recipeViewModel = postedRecipeViewModel.HydrateRecipeJson();

            isNewRecipe = recipeViewModel.IsNewRecipe();

            // Validation (client validates also ... this to ensure data consistency)
            var validator        = new RecipeViewModelValidator();
            var validationResult = validator.Validate(recipeViewModel);

            if (!validationResult.IsValid)
            {
                if (isNewRecipe)
                {
                    this.AppendMessage(new ErrorMessage {
                        Text = "Did you leave something blank?  Please check your entries and try again."
                    });
                    ViewBag.RecipeCreationOptions = this.RecipeService.GetRecipeCreationOptions();
                    return(this.View("NewRecipe", recipeViewModel));
                }

                // Signals Invalid
                return(this.Content("0"));
            }

            using (var unitOfWork = this.UnitOfWorkFactory.NewUnitOfWork())
            {
                try
                {
                    var recipe = recipeViewModel.IsNewRecipe() ? new Recipe() : this.RecipeService.GetRecipeById(recipeViewModel.RecipeId);

                    // Issue 404 if recipe does not exists or not owned by user
                    if (!isNewRecipe && !recipe.WasCreatedBy(this.ActiveUser.UserId))
                    {
                        return(this.Issue404());
                    }

                    // Map Recipe
                    Mapper.Map(recipeViewModel, recipe);

                    #region INGREDIENT DELETIONS

                    if (!isNewRecipe)
                    {
                        // Delete Fermentables that were removed
                        var fermentablesForDeletion = recipe.Fermentables.Except(recipe.Fermentables.Join(recipeViewModel.Fermentables ?? new List <RecipeFermentableViewModel>(),
                                                                                                          x => x.RecipeFermentableId, y => Converter.Convert <int>(y.Id), (x, y) => x)).ToList();
                        this.RecipeService.MarkRecipeIngredientsForDeletion <RecipeFermentable>(fermentablesForDeletion);

                        // Delete Hops that were removed
                        var hopsForDeletion = recipe.Hops.Except(recipe.Hops.Join(recipeViewModel.Hops ?? new List <RecipeHopViewModel>(),
                                                                                  x => x.RecipeHopId, y => Converter.Convert <int>(y.Id), (x, y) => x)).ToList();
                        this.RecipeService.MarkRecipeIngredientsForDeletion <RecipeHop>(hopsForDeletion);

                        // Delete Yeasts that were removed
                        var yeastsForDeletion = recipe.Yeasts.Except(recipe.Yeasts.Join(recipeViewModel.Yeasts ?? new List <RecipeYeastViewModel>(),
                                                                                        x => x.RecipeYeastId, y => Converter.Convert <int>(y.Id), (x, y) => x)).ToList();
                        this.RecipeService.MarkRecipeIngredientsForDeletion <RecipeYeast>(yeastsForDeletion);

                        // Delete Adjuncts that were removed
                        var adjunctsForDeletion = recipe.Adjuncts.Except(recipe.Adjuncts.Join(recipeViewModel.Others ?? new List <RecipeOtherViewModel>(),
                                                                                              x => x.RecipeAdjunctId, y => Converter.Convert <int>(y.Id), (x, y) => x)).ToList();
                        this.RecipeService.MarkRecipeIngredientsForDeletion <RecipeAdjunct>(adjunctsForDeletion);

                        // Delete MashSteps that were removed
                        var mashStepsForDeletion = recipe.MashSteps.Except(recipe.MashSteps.Join(recipeViewModel.MashSteps ?? new List <RecipeMashStepViewModel>(),
                                                                                                 x => x.RecipeMashStepId, y => Converter.Convert <int>(y.Id), (x, y) => x)).ToList();
                        this.RecipeService.MarkRecipeIngredientsForDeletion <RecipeMashStep>(mashStepsForDeletion);
                    }

                    #endregion

                    #region INGREDIENT ADDITIONS

                    // Add Fermentables
                    if (recipeViewModel.Fermentables != null)
                    {
                        recipeViewModel.Fermentables.Where(x => Converter.Convert <int>(x.Id) == 0)
                        .ForEach(x => recipe.Fermentables.Add(Mapper.Map(x, new RecipeFermentable())));
                    }

                    // Add Hops
                    if (recipeViewModel.Hops != null)
                    {
                        recipeViewModel.Hops.Where(x => Converter.Convert <int>(x.Id) == 0)
                        .ForEach(x => recipe.Hops.Add(Mapper.Map(x, new RecipeHop())));
                    }

                    // Add Yeasts
                    if (recipeViewModel.Yeasts != null)
                    {
                        recipeViewModel.Yeasts.Where(x => Converter.Convert <int>(x.Id) == 0)
                        .ForEach(x => recipe.Yeasts.Add(Mapper.Map(x, new RecipeYeast())));
                    }

                    // Add Adjuncts
                    if (recipeViewModel.Others != null)
                    {
                        recipeViewModel.Others.Where(x => Converter.Convert <int>(x.Id) == 0)
                        .ForEach(x => recipe.Adjuncts.Add(Mapper.Map(x, new RecipeAdjunct())));
                    }

                    // Add MashStep
                    if (recipeViewModel.MashSteps != null)
                    {
                        recipeViewModel.MashSteps.Where(x => Converter.Convert <int>(x.Id) == 0)
                        .ForEach(x => recipe.MashSteps.Add(Mapper.Map(x, new RecipeMashStep())));
                    }

                    #endregion

                    #region INGREDIENT UPDATES

                    if (!isNewRecipe)
                    {
                        // Update Fermentables
                        if (recipeViewModel.Fermentables != null)
                        {
                            foreach (var recipeFermentableViewModel in recipeViewModel.Fermentables.Where(x => Converter.Convert <int>(x.Id) > 0))
                            {
                                var match = recipe.Fermentables.FirstOrDefault(x => x.RecipeFermentableId == Converter.Convert <int>(recipeFermentableViewModel.Id));
                                if (match == null)
                                {
                                    throw new InvalidOperationException("Unable to find matching fermentable");
                                }

                                Mapper.Map(recipeFermentableViewModel, match);
                            }
                        }

                        // Update Hops
                        if (recipeViewModel.Hops != null)
                        {
                            foreach (var recipeHopViewModel in recipeViewModel.Hops.Where(x => Converter.Convert <int>(x.Id) > 0))
                            {
                                var match = recipe.Hops.FirstOrDefault(x => x.RecipeHopId == Converter.Convert <int>(recipeHopViewModel.Id));
                                if (match == null)
                                {
                                    throw new InvalidOperationException("Unable to find matching Hop");
                                }

                                Mapper.Map(recipeHopViewModel, match);
                            }
                        }

                        // Update Yeasts
                        if (recipeViewModel.Yeasts != null)
                        {
                            foreach (var recipeYeastViewModel in recipeViewModel.Yeasts.Where(x => Converter.Convert <int>(x.Id) > 0))
                            {
                                var match = recipe.Yeasts.FirstOrDefault(x => x.RecipeYeastId == Converter.Convert <int>(recipeYeastViewModel.Id));
                                if (match == null)
                                {
                                    throw new InvalidOperationException("Unable to find matching Yeast");
                                }

                                Mapper.Map(recipeYeastViewModel, match);
                            }
                        }

                        // Update Adjuncts
                        if (recipeViewModel.Others != null)
                        {
                            foreach (var recipeAdjunctViewModel in recipeViewModel.Others.Where(x => Converter.Convert <int>(x.Id) > 0))
                            {
                                var match = recipe.Adjuncts.FirstOrDefault(x => x.RecipeAdjunctId == Converter.Convert <int>(recipeAdjunctViewModel.Id));
                                if (match == null)
                                {
                                    throw new InvalidOperationException("Unable to find matching Adjunct");
                                }

                                Mapper.Map(recipeAdjunctViewModel, match);
                            }
                        }

                        // Update MashSteps
                        if (recipeViewModel.MashSteps != null)
                        {
                            foreach (var recipeMashStepViewModel in recipeViewModel.MashSteps.Where(x => Converter.Convert <int>(x.Id) > 0))
                            {
                                var match = recipe.MashSteps.FirstOrDefault(x => x.RecipeMashStepId == Converter.Convert <int>(recipeMashStepViewModel.Id));
                                if (match == null)
                                {
                                    throw new InvalidOperationException("Unable to find matching MashStep");
                                }

                                Mapper.Map(recipeMashStepViewModel, match);
                            }
                        }
                    }

                    #endregion

                    #region STEP DELETIONS / ADDITIONS / UPDATES

                    // Deletions
                    if (!isNewRecipe)
                    {
                        var stepsForDeletion = recipe.Steps.Except(recipe.Steps.Join(recipeViewModel.Steps ?? new List <RecipeStepViewModel>(),
                                                                                     x => x.RecipeStepId, y => Converter.Convert <int>(y.Id), (x, y) => x)).ToList();
                        this.RecipeService.MarkRecipeStepsForDeletion(stepsForDeletion);
                    }

                    // Additions
                    if (recipeViewModel.Steps != null)
                    {
                        if (recipe.Steps == null)
                        {
                            recipe.Steps = new List <RecipeStep>();
                        }

                        recipeViewModel.GetSteps()
                        .Where(x => Converter.Convert <int>(x.Id) == 0)
                        .Where(x => !string.IsNullOrWhiteSpace(x.Text))
                        .ForEach(x => recipe.Steps.Add(Mapper.Map(x, new RecipeStep {
                            DateCreated = DateTime.Now
                        })));
                    }

                    // Updates
                    if (!isNewRecipe)
                    {
                        if (recipeViewModel.Steps != null)
                        {
                            foreach (var recipeStep in recipeViewModel.GetSteps()
                                     .Where(x => Converter.Convert <int>(x.Id) > 0)
                                     .Where(x => !string.IsNullOrWhiteSpace(x.Text)))
                            {
                                var match = recipe.Steps.FirstOrDefault(x => x.RecipeStepId == Converter.Convert <int>(recipeStep.Id));
                                if (match == null)
                                {
                                    throw new InvalidOperationException("Unable to find matching step");
                                }

                                match = Mapper.Map(recipeStep, match);
                                match.DateModified = DateTime.Now;
                            }
                        }
                    }

                    #endregion

                    // Save the Image
                    if (isNewRecipe)
                    {
                        if (recipeViewModel.PhotoForUpload != null)
                        {
                            // Save the New Image
                            recipe.ImageUrlRoot = this.StaticContentService.SaveRecipeImage(recipeViewModel.PhotoForUpload.InputStream,
                                                                                            this.WebSettings.MediaPhysicalRoot);
                        }
                    }

                    // Finalize Recipe
                    this.RecipeService.FinalizeRecipe(recipe);

                    unitOfWork.Commit();

                    if (isNewRecipe)
                    {
                        this.ForwardMessage(new SuccessMessage {
                            Text = BrewgrMessages.RecipeSaved
                        });
                        return(Redirect(Url.RecipeEditUrl(recipe.RecipeId)));
                    }
                    else
                    {
                        // Signals Success
                        return(Content("1"));
                    }
                }
                catch (Exception ex)
                {
                    this.LogHandledException(ex);
                    unitOfWork.Rollback();

                    if (isNewRecipe)
                    {
                        ViewBag.RecipeCreationOptions = this.RecipeService.GetRecipeCreationOptions();
                        this.AppendMessage(new ErrorMessage {
                            Text = GenericMessages.ErrorMessage
                        });
                        return(View("NewRecipe", recipeViewModel));
                    }
                    else
                    {
                        // Signals Failure
                        return(Content("-1"));
                    }
                }
            }
        }
Ejemplo n.º 2
0
		public ActionResult SaveRecipe(PostedRecipeViewModel postedRecipeViewModel)
		{
			// NOTE: This action handles saving for both new recipes
			// and edited recipes.  New Recipes post to this action while
			// edits post to this action via Ajax.

			var isNewRecipe = false;

			// Hydrate JSON ReceipeViewModel
			var recipeViewModel = postedRecipeViewModel.HydrateRecipeJson();
			isNewRecipe = recipeViewModel.IsNewRecipe();

			// Validation (client validates also ... this to ensure data consistency)
			var validator = new RecipeViewModelValidator();
			var validationResult = validator.Validate(recipeViewModel);
			if(!validationResult.IsValid)
			{
				if(isNewRecipe)
				{
					this.AppendMessage(new ErrorMessage { Text = "Did you leave something blank?  Please check your entries and try again."});
					ViewBag.RecipeCreationOptions = this.RecipeService.GetRecipeCreationOptions();
					return this.View("NewRecipe", recipeViewModel);
				}

				// Signals Invalid
				return this.Content("0");
			}

			using (var unitOfWork = this.UnitOfWorkFactory.NewUnitOfWork())
			{				
				try
				{
					var recipe = recipeViewModel.IsNewRecipe() ? new Recipe() : this.RecipeService.GetRecipeById(recipeViewModel.RecipeId);

					// Issue 404 if recipe does not exists or not owned by user
					if (!isNewRecipe && !recipe.WasCreatedBy(this.ActiveUser.UserId))
					{
						return this.Issue404();
					}

					// Map Recipe
					Mapper.Map(recipeViewModel, recipe);

					#region INGREDIENT DELETIONS

					if(!isNewRecipe)
					{
						// Delete Fermentables that were removed
						var fermentablesForDeletion = recipe.Fermentables.Except(recipe.Fermentables.Join(recipeViewModel.Fermentables ?? new List<RecipeFermentableViewModel>(),
							x => x.RecipeFermentableId, y => Converter.Convert<int>(y.Id), (x, y) => x)).ToList();
						this.RecipeService.MarkRecipeIngredientsForDeletion<RecipeFermentable>(fermentablesForDeletion);

						// Delete Hops that were removed
						var hopsForDeletion = recipe.Hops.Except(recipe.Hops.Join(recipeViewModel.Hops ?? new List<RecipeHopViewModel>(),
							x => x.RecipeHopId, y => Converter.Convert<int>(y.Id), (x, y) => x)).ToList();
						this.RecipeService.MarkRecipeIngredientsForDeletion<RecipeHop>(hopsForDeletion);

						// Delete Yeasts that were removed
						var yeastsForDeletion = recipe.Yeasts.Except(recipe.Yeasts.Join(recipeViewModel.Yeasts ?? new List<RecipeYeastViewModel>(),
							x => x.RecipeYeastId, y => Converter.Convert<int>(y.Id), (x, y) => x)).ToList();
						this.RecipeService.MarkRecipeIngredientsForDeletion<RecipeYeast>(yeastsForDeletion);

						// Delete Adjuncts that were removed
						var adjunctsForDeletion = recipe.Adjuncts.Except(recipe.Adjuncts.Join(recipeViewModel.Others ?? new List<RecipeOtherViewModel>(),
							x => x.RecipeAdjunctId, y => Converter.Convert<int>(y.Id), (x, y) => x)).ToList();
						this.RecipeService.MarkRecipeIngredientsForDeletion<RecipeAdjunct>(adjunctsForDeletion);

                        // Delete MashSteps that were removed
                        var mashStepsForDeletion = recipe.MashSteps.Except(recipe.MashSteps.Join(recipeViewModel.MashSteps ?? new List<RecipeMashStepViewModel>(),
                            x => x.RecipeMashStepId, y => Converter.Convert<int>(y.Id), (x, y) => x)).ToList();
                        this.RecipeService.MarkRecipeIngredientsForDeletion<RecipeMashStep>(mashStepsForDeletion);
					}

					#endregion

					#region INGREDIENT ADDITIONS

					// Add Fermentables
					if (recipeViewModel.Fermentables != null)
					{
						recipeViewModel.Fermentables.Where(x => Converter.Convert<int>(x.Id) == 0)
							.ForEach(x => recipe.Fermentables.Add(Mapper.Map(x, new RecipeFermentable())));
					}

					// Add Hops
					if (recipeViewModel.Hops != null)
					{
						recipeViewModel.Hops.Where(x => Converter.Convert<int>(x.Id) == 0)
							.ForEach(x => recipe.Hops.Add(Mapper.Map(x, new RecipeHop())));
					}

					// Add Yeasts
					if (recipeViewModel.Yeasts != null)
					{
						recipeViewModel.Yeasts.Where(x => Converter.Convert<int>(x.Id) == 0)
							.ForEach(x => recipe.Yeasts.Add(Mapper.Map(x, new RecipeYeast())));
					}

					// Add Adjuncts
					if (recipeViewModel.Others != null)
					{
						recipeViewModel.Others.Where(x => Converter.Convert<int>(x.Id) == 0)
							.ForEach(x => recipe.Adjuncts.Add(Mapper.Map(x, new RecipeAdjunct())));
					}

                    // Add MashStep
                    if (recipeViewModel.MashSteps != null)
                    {
                        recipeViewModel.MashSteps.Where(x => Converter.Convert<int>(x.Id) == 0)
                            .ForEach(x => recipe.MashSteps.Add(Mapper.Map(x, new RecipeMashStep())));
                    }

					#endregion

					#region INGREDIENT UPDATES

					if (!isNewRecipe)
					{
						// Update Fermentables
						if (recipeViewModel.Fermentables != null)
						{
							foreach (var recipeFermentableViewModel in recipeViewModel.Fermentables.Where(x => Converter.Convert<int>(x.Id) > 0))
							{
								var match = recipe.Fermentables.FirstOrDefault(x => x.RecipeFermentableId == Converter.Convert<int>(recipeFermentableViewModel.Id));
								if (match == null)
								{
									throw new InvalidOperationException("Unable to find matching fermentable");
								}

								Mapper.Map(recipeFermentableViewModel, match);
							}
						}

						// Update Hops
						if (recipeViewModel.Hops != null)
						{
							foreach (var recipeHopViewModel in recipeViewModel.Hops.Where(x => Converter.Convert<int>(x.Id) > 0))
							{
								var match = recipe.Hops.FirstOrDefault(x => x.RecipeHopId == Converter.Convert<int>(recipeHopViewModel.Id));
								if (match == null)
								{
									throw new InvalidOperationException("Unable to find matching Hop");
								}

								Mapper.Map(recipeHopViewModel, match);
							}
						}

						// Update Yeasts
						if (recipeViewModel.Yeasts != null)
						{
							foreach (var recipeYeastViewModel in recipeViewModel.Yeasts.Where(x => Converter.Convert<int>(x.Id) > 0))
							{
								var match = recipe.Yeasts.FirstOrDefault(x => x.RecipeYeastId == Converter.Convert<int>(recipeYeastViewModel.Id));
								if (match == null)
								{
									throw new InvalidOperationException("Unable to find matching Yeast");
								}

								Mapper.Map(recipeYeastViewModel, match);
							}
						}

						// Update Adjuncts
						if (recipeViewModel.Others != null)
						{
							foreach (var recipeAdjunctViewModel in recipeViewModel.Others.Where(x => Converter.Convert<int>(x.Id) > 0))
							{
								var match = recipe.Adjuncts.FirstOrDefault(x => x.RecipeAdjunctId == Converter.Convert<int>(recipeAdjunctViewModel.Id));
								if (match == null)
								{
									throw new InvalidOperationException("Unable to find matching Adjunct");
								}

								Mapper.Map(recipeAdjunctViewModel, match);
							}
						}

                        // Update MashSteps
                        if (recipeViewModel.MashSteps != null)
                        {
                            foreach (var recipeMashStepViewModel in recipeViewModel.MashSteps.Where(x => Converter.Convert<int>(x.Id) > 0))
                            {
                                var match = recipe.MashSteps.FirstOrDefault(x => x.RecipeMashStepId == Converter.Convert<int>(recipeMashStepViewModel.Id));
                                if (match == null)
                                {
                                    throw new InvalidOperationException("Unable to find matching MashStep");
                                }

                                Mapper.Map(recipeMashStepViewModel, match);
                            }
                        }
					}

					#endregion

					#region STEP DELETIONS / ADDITIONS / UPDATES

					// Deletions
					if (!isNewRecipe)
					{
						var stepsForDeletion = recipe.Steps.Except(recipe.Steps.Join(recipeViewModel.Steps ?? new List<RecipeStepViewModel>(),
							x => x.RecipeStepId, y => Converter.Convert<int>(y.Id), (x, y) => x)).ToList();
						this.RecipeService.MarkRecipeStepsForDeletion(stepsForDeletion);
					}

					// Additions
					if (recipeViewModel.Steps != null)
					{
						if(recipe.Steps == null)
						{
							recipe.Steps = new List<RecipeStep>();
						}

						recipeViewModel.GetSteps()
							.Where(x => Converter.Convert<int>(x.Id) == 0)
							.Where(x => !string.IsNullOrWhiteSpace(x.Text))
							.ForEach(x => recipe.Steps.Add(Mapper.Map(x, new RecipeStep { DateCreated = DateTime.Now })));
					}

					// Updates
					if (!isNewRecipe)
					{
						if (recipeViewModel.Steps != null)
						{
							foreach (var recipeStep in recipeViewModel.GetSteps()
								.Where(x => Converter.Convert<int>(x.Id) > 0)
								.Where(x => !string.IsNullOrWhiteSpace(x.Text)))
							{
								var match = recipe.Steps.FirstOrDefault(x => x.RecipeStepId == Converter.Convert<int>(recipeStep.Id));
								if (match == null)
								{
									throw new InvalidOperationException("Unable to find matching step");
								}

								match = Mapper.Map(recipeStep, match);
								match.DateModified = DateTime.Now;
							}
						}
					}

					#endregion

					// Save the Image
					if(isNewRecipe)
					{
						if(recipeViewModel.PhotoForUpload != null)
						{
							// Save the New Image
							recipe.ImageUrlRoot = this.StaticContentService.SaveRecipeImage(recipeViewModel.PhotoForUpload.InputStream,
								this.WebSettings.MediaPhysicalRoot);
						}
					}

					// Finalize Recipe
					this.RecipeService.FinalizeRecipe(recipe);

					unitOfWork.Commit();

					if(isNewRecipe)
					{
						this.ForwardMessage(new SuccessMessage { Text = BrewgrMessages.RecipeSaved });
						return Redirect(Url.RecipeEditUrl(recipe.RecipeId));
					}
					else
					{
						// Signals Success
						return Content("1");
					}
				}
				catch (Exception ex)
				{
					this.LogHandledException(ex);
					unitOfWork.Rollback();

					if(isNewRecipe)
					{
						ViewBag.RecipeCreationOptions = this.RecipeService.GetRecipeCreationOptions();
						this.AppendMessage(new ErrorMessage { Text = GenericMessages.ErrorMessage });
						return View("NewRecipe", recipeViewModel);
					}
					else
					{
						// Signals Failure
						return Content("-1");
					}
				}
			}
		}