/// <summary> /// Exports a recipe to the Beer Xml Format /// </summary> public string Export(Recipe recipe) { if (recipe == null) { throw new ArgumentNullException("recipe"); } // Build the Recipe Node var recipeXml = new XElement("RECIPE", new XElement("WATER"), new XElement("EQUIPMENT"), new XElement("NAME", recipe.RecipeName + " (exported from brewgr.com)"), new XElement("VERSION", "1"), new XElement("TYPE", HumanReadableFormatter.AddSpacesToPascalCaseString(((RecipeType)recipe.RecipeTypeId).ToString())), new XElement("BREWER", recipe.User.CalculatedUsername + string.Format(" ({0}/!/{1})", this.WebSettings.RootPath, recipe.User.CalculatedUsername)), new XElement("BATCH_SIZE", recipe.GetUnitType() == UnitType.Metric ? recipe.BatchSize : this.RecipeUnitConverter.ConvertGallonsToLiters(recipe.BatchSize)), new XElement("BOIL_SIZE", recipe.GetUnitType() == UnitType.Metric ? recipe.BoilSize : this.RecipeUnitConverter.ConvertGallonsToLiters(recipe.BoilSize)), new XElement("BOIL_TIME", recipe.BoilTime), new XElement("EFFICIENCY", recipe.Efficiency * 100), new XElement("NOTES", this.GetNotes(recipe)), new XElement("IBU_METHOD", this.GetIbuMethod(recipe))); // Hops recipeXml.Add(new XElement("HOPS", recipe.Hops.Select(x => new XElement("HOP", new XElement("NAME", x.Hop.Name), new XElement("VERSION", "1"), new XElement("ALPHA", x.AlphaAcidAmount), new XElement("AMOUNT", recipe.GetUnitType() == UnitType.Metric ? RecipeUnitConverter.ConvertGramsToKilograms(x.Amount) : RecipeUnitConverter.ConvertOuncesToKilograms(x.Amount)), new XElement("USE", this.GetHopUsageText(x.HopUsageTypeId)), new XElement("TIME", x.TimeInMinutes) )))); // Fermentables recipeXml.Add(new XElement("FERMENTABLES", recipe.Fermentables.Select(x => new XElement("FERMENTABLE", new XElement("NAME", x.Fermentable.Name), new XElement("VERSION", "1"), new XElement("AMOUNT", recipe.GetUnitType() == UnitType.Metric ? x.Amount : RecipeUnitConverter.ConvertPoundsToKilograms(x.Amount)), new XElement("TYPE", this.GetFermentableUsageText(x.FermentableUsageTypeId, x.Fermentable.Name)), new XElement("YIELD", (x.Ppg / 46.214 / 0.01)), new XElement("COLOR", x.Lovibond) )))); // Yeast recipeXml.Add(new XElement("YEASTS", recipe.Yeasts.Select(x => new XElement("YEAST", new XElement("NAME", x.Yeast.Name), new XElement("VERSION", "1"), new XElement("TYPE", x.Yeast.Name.ToLower().IndexOf("lager") > -1 ? "Lager" : "Ale"), new XElement("FORM", this.GetYeastFormFromName(x.Yeast.Name)), new XElement("ATTENUATION", x.Attenuation * 100) )))); // Miscs recipeXml.Add(new XElement("MISCS", recipe.Adjuncts.Select(x => new XElement("MISC", new XElement("NAME", x.Adjunct.Name), new XElement("VERSION", "1"), this.GetAdjuctAmountElements(x), new XElement("TYPE", "other"), this.GetAdjunctUsageElement(x) )))); // Style if (!string.IsNullOrWhiteSpace(recipe.BjcpStyleSubCategoryId)) { var style = this.BeerStyleService.GetStyleBySubCategoryId(recipe.BjcpStyleSubCategoryId); recipeXml.Add(new XElement("STYLE", new XElement("NAME", style.SubCategoryName), new XElement("VERSION", "1"), new XElement("CATEGORY_NUMBER", style.CategoryId), new XElement("STYLE_LETTER", style.SubCategoryId.Replace(style.CategoryId.ToString(), "")), new XElement("STYLE_GUIDE", "BJCP"), new XElement("TYPE", this.GetStyleTypeText(style)), new XElement("OG_MIN", style.Og_Low), new XElement("OG_MAX", style.Og_High), new XElement("FG_MIN", style.Fg_Low), new XElement("FG_MAX", style.Fg_High), new XElement("IBU_MIN", style.Ibu_Low), new XElement("IBU_MAX", style.Ibu_High), new XElement("COLOR_MIN", style.Srm_Low), new XElement("COLOR_MAX", style.Srm_High) )); } else { recipeXml.Add(new XElement("STYLE")); } // Build the Doc var xdoc = new XDocument( new XDeclaration("1.0", null, null), new XElement("RECIPES", recipeXml) ); return(xdoc.ToString()); }