|
|
|
@ -1,17 +1,22 @@ |
|
|
|
|
package com.mousetech.gourmetj; |
|
|
|
|
|
|
|
|
|
import java.io.ByteArrayOutputStream; |
|
|
|
|
import java.io.PrintWriter; |
|
|
|
|
import java.io.Serializable; |
|
|
|
|
import java.util.ArrayList; |
|
|
|
|
import java.util.Comparator; |
|
|
|
|
import java.util.List; |
|
|
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
|
|
import javax.annotation.PostConstruct; |
|
|
|
|
import javax.faces.event.AjaxBehaviorEvent; |
|
|
|
|
import javax.faces.view.ViewScoped; |
|
|
|
|
import javax.inject.Inject; |
|
|
|
|
import javax.inject.Named; |
|
|
|
|
|
|
|
|
|
import org.apache.commons.lang3.StringUtils; |
|
|
|
|
import org.primefaces.model.ByteArrayContent; |
|
|
|
|
import org.primefaces.model.DefaultStreamedContent; |
|
|
|
|
import org.primefaces.model.StreamedContent; |
|
|
|
|
import org.slf4j.Logger; |
|
|
|
|
import org.slf4j.LoggerFactory; |
|
|
|
|
|
|
|
|
@ -19,11 +24,57 @@ import com.mousetech.gourmetj.persistence.dao.ShopcatRepository; |
|
|
|
|
import com.mousetech.gourmetj.persistence.model.Ingredient; |
|
|
|
|
import com.mousetech.gourmetj.persistence.model.Recipe; |
|
|
|
|
import com.mousetech.gourmetj.persistence.model.Shopcat; |
|
|
|
|
import com.mousetech.gourmetj.utils.YamlShoppingList; |
|
|
|
|
|
|
|
|
|
@Named |
|
|
|
|
@ViewScoped |
|
|
|
|
public class ShoppingListBean implements Serializable { |
|
|
|
|
|
|
|
|
|
public class RecipeReference { |
|
|
|
|
|
|
|
|
|
private int count; |
|
|
|
|
private Recipe recipe; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Constructor Constructor. |
|
|
|
|
* |
|
|
|
|
* @param r Recipe to reference (from Shopping List) |
|
|
|
|
*/ |
|
|
|
|
public RecipeReference(Recipe r) { |
|
|
|
|
count = 1; |
|
|
|
|
recipe = r; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* @return the count |
|
|
|
|
*/ |
|
|
|
|
public int getCount() { |
|
|
|
|
return count; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* @param count the count to set |
|
|
|
|
*/ |
|
|
|
|
public void setCount(int count) { |
|
|
|
|
this.count = count; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* @return the recipe |
|
|
|
|
*/ |
|
|
|
|
public Recipe getRecipe() { |
|
|
|
|
return recipe; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* @param recipe the recipe to set |
|
|
|
|
*/ |
|
|
|
|
public void setRecipe(Recipe recipe) { |
|
|
|
|
this.recipe = recipe; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Serial version for session save/restore |
|
|
|
|
*/ |
|
|
|
@ -41,7 +92,7 @@ public class ShoppingListBean implements Serializable { |
|
|
|
|
|
|
|
|
|
private List<ShopIngredient> siList; |
|
|
|
|
|
|
|
|
|
// private List<ShopIngredient> ingredientList;
|
|
|
|
|
private List<RecipeReference> recipeList; |
|
|
|
|
|
|
|
|
|
@PostConstruct |
|
|
|
|
public void init() { |
|
|
|
@ -50,8 +101,19 @@ public class ShoppingListBean implements Serializable { |
|
|
|
|
buildMaps(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public List<Recipe> getRecipeList() { |
|
|
|
|
return this.userSession.getShoppingList(); |
|
|
|
|
public List<RecipeReference> getRecipeList() { |
|
|
|
|
if (this.recipeList == null) { |
|
|
|
|
this.recipeList = loadRecipeList(); |
|
|
|
|
} |
|
|
|
|
return this.recipeList; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private List<RecipeReference> loadRecipeList() { |
|
|
|
|
List<RecipeReference> list = |
|
|
|
|
userSession.getShoppingList().stream() |
|
|
|
|
.map(r -> new RecipeReference(r)) |
|
|
|
|
.collect(Collectors.toList()); |
|
|
|
|
return list; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public List<ShopIngredient> getIngredientList() { |
|
|
|
@ -59,7 +121,8 @@ public class ShoppingListBean implements Serializable { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void buildMaps() { |
|
|
|
|
for (Recipe r : this.getRecipeList()) { |
|
|
|
|
this.siList = new ArrayList<ShopIngredient>(30); |
|
|
|
|
for (RecipeReference r : this.getRecipeList()) { |
|
|
|
|
buildMapsFor(r); |
|
|
|
|
} |
|
|
|
|
// Now consolidate amounts and sort by
|
|
|
|
@ -77,8 +140,13 @@ public class ShoppingListBean implements Serializable { |
|
|
|
|
* |
|
|
|
|
* @see #buildMaps() |
|
|
|
|
*/ |
|
|
|
|
private void buildMapsFor(Recipe r) { |
|
|
|
|
for (Ingredient ing : r.getIngredientHash()) { |
|
|
|
|
private void buildMapsFor(RecipeReference r) { |
|
|
|
|
final int multiplier = r.getCount(); |
|
|
|
|
if (multiplier == 0) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
for (Ingredient ing : r.getRecipe() |
|
|
|
|
.getIngredientHash()) { |
|
|
|
|
String ingkey = ing.getIngkey(); |
|
|
|
|
if (StringUtils.isBlank(ingkey)) { |
|
|
|
|
continue; |
|
|
|
@ -86,10 +154,21 @@ public class ShoppingListBean implements Serializable { |
|
|
|
|
String shopCatName = ing.getShopCat() != null |
|
|
|
|
? ing.getShopCat().getShopcategory() |
|
|
|
|
: null; |
|
|
|
|
ShopIngredient sing = new ShopIngredient( |
|
|
|
|
ing.getAmount(), ing.getUnit(), |
|
|
|
|
ing.getItem(), ing.getIngkey(), shopCatName); |
|
|
|
|
siList.add(sing); |
|
|
|
|
ShopIngredient sing; |
|
|
|
|
try { |
|
|
|
|
Double amt = ing.getAmount(); |
|
|
|
|
if (multiplier > 1 && (amt != null)) { |
|
|
|
|
amt *= multiplier; |
|
|
|
|
} |
|
|
|
|
sing = new ShopIngredient(amt, ing.getUnit(), |
|
|
|
|
ing.getItem(), ing.getIngkey(), |
|
|
|
|
shopCatName); |
|
|
|
|
siList.add(sing); |
|
|
|
|
} catch (Exception e) { |
|
|
|
|
log.error("Unable to create ShopIngredient for " |
|
|
|
|
+ r.getRecipe() + " Ingredient " + ing); |
|
|
|
|
e.printStackTrace(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -150,6 +229,12 @@ public class ShoppingListBean implements Serializable { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public StreamedContent getDlIngredientList() { |
|
|
|
|
return YamlShoppingList |
|
|
|
|
.createDownload(getIngredientList()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// =============================================
|
|
|
|
|
private List<String> shopcatList; |
|
|
|
|
|
|
|
|
|
public List<String> getShopcatList() { |
|
|
|
@ -211,6 +296,15 @@ public class ShoppingListBean implements Serializable { |
|
|
|
|
this.shopcatList = null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Primefaces AJAX listener for changes to amount values of |
|
|
|
|
* recipes the recipe list. Forces re-computation of |
|
|
|
|
* ingredient requirements. |
|
|
|
|
*/ |
|
|
|
|
public void pfAmountChange() { |
|
|
|
|
buildMaps(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// ===
|
|
|
|
|
private String selectedShopcat; |
|
|
|
|
|
|
|
|
@ -291,12 +385,12 @@ public class ShoppingListBean implements Serializable { |
|
|
|
|
return; // effective NO-OP
|
|
|
|
|
} |
|
|
|
|
newCat = newCat.trim(); |
|
|
|
|
if ( StringUtils.isBlank(newCat)) { |
|
|
|
|
if (StringUtils.isBlank(newCat)) { |
|
|
|
|
this.shopcatRepository |
|
|
|
|
.deleteShopcatFor(this.getSelectedIngkey()); |
|
|
|
|
.deleteShopcatFor(this.getSelectedIngkey()); |
|
|
|
|
} else { |
|
|
|
|
this.shopcatRepository |
|
|
|
|
.updateShopcatFor(newCat, this.getSelectedIngkey()); |
|
|
|
|
this.shopcatRepository.updateShopcatFor(newCat, |
|
|
|
|
this.getSelectedIngkey()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|