Have downloadable shopping list
This commit is contained in:
parent
75a8487cfb
commit
18410682de
|
@ -25,7 +25,7 @@ public class ShopIngredient implements Comparable<Object> {
|
|||
* @param ingkey
|
||||
* @param shopCat
|
||||
*/
|
||||
public ShopIngredient( double amount, String unit,
|
||||
public ShopIngredient( Double amount, String unit,
|
||||
String item, String ingkey,
|
||||
String shopCat) {
|
||||
this.amount = amount;
|
||||
|
@ -68,14 +68,14 @@ public class ShopIngredient implements Comparable<Object> {
|
|||
/**
|
||||
* @return the amount
|
||||
*/
|
||||
public double getAmount() {
|
||||
public Double getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param amount the amount to set
|
||||
*/
|
||||
public void setAmount(double amount) {
|
||||
public void setAmount(Double amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
|
@ -83,8 +83,12 @@ public class ShopIngredient implements Comparable<Object> {
|
|||
* @return the displayAmount
|
||||
*/
|
||||
public String getDisplayAmount() {
|
||||
Double amt = this.getAmount();
|
||||
if ( amt == null) {
|
||||
return "";
|
||||
}
|
||||
return IngredientDigester.displayAmount(
|
||||
IngredientAmountFormat.IA_TEXT, this.getAmount(),
|
||||
IngredientAmountFormat.IA_TEXT, amt,
|
||||
null);
|
||||
}
|
||||
|
||||
|
@ -112,7 +116,7 @@ public class ShopIngredient implements Comparable<Object> {
|
|||
}
|
||||
|
||||
private String ingkey;
|
||||
private double amount;
|
||||
private Double amount;
|
||||
private String displayAmount;
|
||||
private String unit;
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ textarea {
|
|||
}
|
||||
|
||||
#footer {
|
||||
position: absolute;
|
||||
bottom: 90px;
|
||||
width: 100%;
|
||||
}
|
|
@ -33,7 +33,9 @@
|
|||
<f:selectItems
|
||||
value="#{userSession.searchTypeList}"
|
||||
/>
|
||||
<p:ajax listener="#{adminMainBean.resetSuggestions}"/>
|
||||
<p:ajax
|
||||
listener="#{adminMainBean.resetSuggestions}"
|
||||
/>
|
||||
</p:selectOneMenu>
|
||||
<p:commandButton id="ctlClear" value="Clear"
|
||||
icon="ui-icon-close"
|
||||
|
@ -46,6 +48,13 @@
|
|||
<p:commandButton value="More..."
|
||||
action="#{adminMainBean.doMore}"
|
||||
/>
|
||||
<h:outputText id="slistSSize"
|
||||
style="margin-left: 2em"
|
||||
value="#{userSession.shoppingList.size()}"
|
||||
/>
|
||||
<h:outputLabel for="slistSize"
|
||||
value=" Recipes in Shopping List"
|
||||
/>
|
||||
</div>
|
||||
</h:form>
|
||||
<h:form id="form2">
|
||||
|
|
|
@ -23,6 +23,15 @@
|
|||
border-width: 0;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
.noRecipe {
|
||||
text-decoration: line-through;
|
||||
color: gray;
|
||||
}
|
||||
|
||||
.plusRecipe {
|
||||
|
||||
}
|
||||
</style>
|
||||
<h:messages />
|
||||
<p:tabView id="tabGroupClient" orientation="left"
|
||||
|
@ -38,11 +47,31 @@
|
|||
<f:facet name="header">
|
||||
<h:outputText value="Recipes" />
|
||||
</f:facet>
|
||||
<p:column style="width: 4em">
|
||||
<p:spinner required="true" min="0"
|
||||
value="#{item.count}" size="1"
|
||||
>
|
||||
<p:ajax
|
||||
listener="#{shoppingListBean.pfAmountChange}"
|
||||
update="@form:tblShopIngredients rname"
|
||||
/>
|
||||
</p:spinner>
|
||||
</p:column>
|
||||
<p:column>
|
||||
<h:outputText value="#{item.title}" />
|
||||
<h:outputText id="rname"
|
||||
styleClass="#{(item.count eq 0) ? 'noRecipe' :'plusRecipe' }"
|
||||
value="#{item.recipe.title}"
|
||||
/>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
<!-- ====== Ingredients ============================ -->
|
||||
<!-- ====== Ingredients To Buy ======================= -->
|
||||
<p:column id="dlIng">
|
||||
<p:commandButton value="Download List" ajax="false">
|
||||
<p:fileDownload
|
||||
value="#{shoppingListBean.dlIngredientList}"
|
||||
/>
|
||||
</p:commandButton>
|
||||
</p:column>
|
||||
<p:column id="ingredientsc"
|
||||
style="width: 25%; vertical-align: top;"
|
||||
>
|
||||
|
@ -64,11 +93,6 @@
|
|||
/>
|
||||
</p:column>
|
||||
</p:headerRow>
|
||||
<p:column label="ingKey">
|
||||
<h:outputText
|
||||
value="#{item.ingkey}"
|
||||
/>
|
||||
</p:column>
|
||||
<p:column label="Amt"
|
||||
style="width: 3em; text-align: right"
|
||||
>
|
||||
|
@ -95,11 +119,17 @@
|
|||
</h:form>
|
||||
</p:tab>
|
||||
<!-- -->
|
||||
<p:tab id="ingshopcatEditTab" title="Edit">
|
||||
<p:tab id="ingshopcatEditTab"
|
||||
title="Edit Shopping Categories"
|
||||
>
|
||||
<ui:include
|
||||
src="/WEB-INF/layout/misctabs/ingshopkey.xhtml"
|
||||
/>
|
||||
</p:tab>
|
||||
<!-- -->
|
||||
<p:tab id="tabImportExport" title="Import/Export">
|
||||
<h:outputText value="For future implementation" />
|
||||
</p:tab>
|
||||
</p:tabView>
|
||||
<h:form id="frmHome">
|
||||
<p:commandButton id="doHome" value="Home"
|
||||
|
|
Loading…
Reference in New Issue
Block a user