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 ingkey
|
||||||
* @param shopCat
|
* @param shopCat
|
||||||
*/
|
*/
|
||||||
public ShopIngredient( double amount, String unit,
|
public ShopIngredient( Double amount, String unit,
|
||||||
String item, String ingkey,
|
String item, String ingkey,
|
||||||
String shopCat) {
|
String shopCat) {
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
|
@ -68,14 +68,14 @@ public class ShopIngredient implements Comparable<Object> {
|
||||||
/**
|
/**
|
||||||
* @return the amount
|
* @return the amount
|
||||||
*/
|
*/
|
||||||
public double getAmount() {
|
public Double getAmount() {
|
||||||
return amount;
|
return amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param amount the amount to set
|
* @param amount the amount to set
|
||||||
*/
|
*/
|
||||||
public void setAmount(double amount) {
|
public void setAmount(Double amount) {
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,8 +83,12 @@ public class ShopIngredient implements Comparable<Object> {
|
||||||
* @return the displayAmount
|
* @return the displayAmount
|
||||||
*/
|
*/
|
||||||
public String getDisplayAmount() {
|
public String getDisplayAmount() {
|
||||||
|
Double amt = this.getAmount();
|
||||||
|
if ( amt == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
return IngredientDigester.displayAmount(
|
return IngredientDigester.displayAmount(
|
||||||
IngredientAmountFormat.IA_TEXT, this.getAmount(),
|
IngredientAmountFormat.IA_TEXT, amt,
|
||||||
null);
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +116,7 @@ public class ShopIngredient implements Comparable<Object> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String ingkey;
|
private String ingkey;
|
||||||
private double amount;
|
private Double amount;
|
||||||
private String displayAmount;
|
private String displayAmount;
|
||||||
private String unit;
|
private String unit;
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,22 @@
|
||||||
package com.mousetech.gourmetj;
|
package com.mousetech.gourmetj;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.PrintWriter;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import javax.faces.event.AjaxBehaviorEvent;
|
|
||||||
import javax.faces.view.ViewScoped;
|
import javax.faces.view.ViewScoped;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
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.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
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.Ingredient;
|
||||||
import com.mousetech.gourmetj.persistence.model.Recipe;
|
import com.mousetech.gourmetj.persistence.model.Recipe;
|
||||||
import com.mousetech.gourmetj.persistence.model.Shopcat;
|
import com.mousetech.gourmetj.persistence.model.Shopcat;
|
||||||
|
import com.mousetech.gourmetj.utils.YamlShoppingList;
|
||||||
|
|
||||||
@Named
|
@Named
|
||||||
@ViewScoped
|
@ViewScoped
|
||||||
public class ShoppingListBean implements Serializable {
|
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
|
* Serial version for session save/restore
|
||||||
*/
|
*/
|
||||||
|
@ -41,7 +92,7 @@ public class ShoppingListBean implements Serializable {
|
||||||
|
|
||||||
private List<ShopIngredient> siList;
|
private List<ShopIngredient> siList;
|
||||||
|
|
||||||
// private List<ShopIngredient> ingredientList;
|
private List<RecipeReference> recipeList;
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
|
@ -50,8 +101,19 @@ public class ShoppingListBean implements Serializable {
|
||||||
buildMaps();
|
buildMaps();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Recipe> getRecipeList() {
|
public List<RecipeReference> getRecipeList() {
|
||||||
return this.userSession.getShoppingList();
|
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() {
|
public List<ShopIngredient> getIngredientList() {
|
||||||
|
@ -59,7 +121,8 @@ public class ShoppingListBean implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buildMaps() {
|
private void buildMaps() {
|
||||||
for (Recipe r : this.getRecipeList()) {
|
this.siList = new ArrayList<ShopIngredient>(30);
|
||||||
|
for (RecipeReference r : this.getRecipeList()) {
|
||||||
buildMapsFor(r);
|
buildMapsFor(r);
|
||||||
}
|
}
|
||||||
// Now consolidate amounts and sort by
|
// Now consolidate amounts and sort by
|
||||||
|
@ -77,8 +140,13 @@ public class ShoppingListBean implements Serializable {
|
||||||
*
|
*
|
||||||
* @see #buildMaps()
|
* @see #buildMaps()
|
||||||
*/
|
*/
|
||||||
private void buildMapsFor(Recipe r) {
|
private void buildMapsFor(RecipeReference r) {
|
||||||
for (Ingredient ing : r.getIngredientHash()) {
|
final int multiplier = r.getCount();
|
||||||
|
if (multiplier == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (Ingredient ing : r.getRecipe()
|
||||||
|
.getIngredientHash()) {
|
||||||
String ingkey = ing.getIngkey();
|
String ingkey = ing.getIngkey();
|
||||||
if (StringUtils.isBlank(ingkey)) {
|
if (StringUtils.isBlank(ingkey)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -86,10 +154,21 @@ public class ShoppingListBean implements Serializable {
|
||||||
String shopCatName = ing.getShopCat() != null
|
String shopCatName = ing.getShopCat() != null
|
||||||
? ing.getShopCat().getShopcategory()
|
? ing.getShopCat().getShopcategory()
|
||||||
: null;
|
: null;
|
||||||
ShopIngredient sing = new ShopIngredient(
|
ShopIngredient sing;
|
||||||
ing.getAmount(), ing.getUnit(),
|
try {
|
||||||
ing.getItem(), ing.getIngkey(), shopCatName);
|
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);
|
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;
|
private List<String> shopcatList;
|
||||||
|
|
||||||
public List<String> getShopcatList() {
|
public List<String> getShopcatList() {
|
||||||
|
@ -211,6 +296,15 @@ public class ShoppingListBean implements Serializable {
|
||||||
this.shopcatList = null;
|
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;
|
private String selectedShopcat;
|
||||||
|
|
||||||
|
@ -291,12 +385,12 @@ public class ShoppingListBean implements Serializable {
|
||||||
return; // effective NO-OP
|
return; // effective NO-OP
|
||||||
}
|
}
|
||||||
newCat = newCat.trim();
|
newCat = newCat.trim();
|
||||||
if ( StringUtils.isBlank(newCat)) {
|
if (StringUtils.isBlank(newCat)) {
|
||||||
this.shopcatRepository
|
this.shopcatRepository
|
||||||
.deleteShopcatFor(this.getSelectedIngkey());
|
.deleteShopcatFor(this.getSelectedIngkey());
|
||||||
} else {
|
} else {
|
||||||
this.shopcatRepository
|
this.shopcatRepository.updateShopcatFor(newCat,
|
||||||
.updateShopcatFor(newCat, this.getSelectedIngkey());
|
this.getSelectedIngkey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,6 @@ textarea {
|
||||||
}
|
}
|
||||||
|
|
||||||
#footer {
|
#footer {
|
||||||
position: absolute;
|
|
||||||
bottom: 90px;
|
bottom: 90px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
|
@ -33,7 +33,9 @@
|
||||||
<f:selectItems
|
<f:selectItems
|
||||||
value="#{userSession.searchTypeList}"
|
value="#{userSession.searchTypeList}"
|
||||||
/>
|
/>
|
||||||
<p:ajax listener="#{adminMainBean.resetSuggestions}"/>
|
<p:ajax
|
||||||
|
listener="#{adminMainBean.resetSuggestions}"
|
||||||
|
/>
|
||||||
</p:selectOneMenu>
|
</p:selectOneMenu>
|
||||||
<p:commandButton id="ctlClear" value="Clear"
|
<p:commandButton id="ctlClear" value="Clear"
|
||||||
icon="ui-icon-close"
|
icon="ui-icon-close"
|
||||||
|
@ -46,6 +48,13 @@
|
||||||
<p:commandButton value="More..."
|
<p:commandButton value="More..."
|
||||||
action="#{adminMainBean.doMore}"
|
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>
|
</div>
|
||||||
</h:form>
|
</h:form>
|
||||||
<h:form id="form2">
|
<h:form id="form2">
|
||||||
|
|
|
@ -23,6 +23,15 @@
|
||||||
border-width: 0;
|
border-width: 0;
|
||||||
border-style: none;
|
border-style: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.noRecipe {
|
||||||
|
text-decoration: line-through;
|
||||||
|
color: gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.plusRecipe {
|
||||||
|
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<h:messages />
|
<h:messages />
|
||||||
<p:tabView id="tabGroupClient" orientation="left"
|
<p:tabView id="tabGroupClient" orientation="left"
|
||||||
|
@ -38,11 +47,31 @@
|
||||||
<f:facet name="header">
|
<f:facet name="header">
|
||||||
<h:outputText value="Recipes" />
|
<h:outputText value="Recipes" />
|
||||||
</f:facet>
|
</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>
|
<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:column>
|
||||||
</p:dataTable>
|
</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"
|
<p:column id="ingredientsc"
|
||||||
style="width: 25%; vertical-align: top;"
|
style="width: 25%; vertical-align: top;"
|
||||||
>
|
>
|
||||||
|
@ -64,11 +93,6 @@
|
||||||
/>
|
/>
|
||||||
</p:column>
|
</p:column>
|
||||||
</p:headerRow>
|
</p:headerRow>
|
||||||
<p:column label="ingKey">
|
|
||||||
<h:outputText
|
|
||||||
value="#{item.ingkey}"
|
|
||||||
/>
|
|
||||||
</p:column>
|
|
||||||
<p:column label="Amt"
|
<p:column label="Amt"
|
||||||
style="width: 3em; text-align: right"
|
style="width: 3em; text-align: right"
|
||||||
>
|
>
|
||||||
|
@ -95,11 +119,17 @@
|
||||||
</h:form>
|
</h:form>
|
||||||
</p:tab>
|
</p:tab>
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<p:tab id="ingshopcatEditTab" title="Edit">
|
<p:tab id="ingshopcatEditTab"
|
||||||
|
title="Edit Shopping Categories"
|
||||||
|
>
|
||||||
<ui:include
|
<ui:include
|
||||||
src="/WEB-INF/layout/misctabs/ingshopkey.xhtml"
|
src="/WEB-INF/layout/misctabs/ingshopkey.xhtml"
|
||||||
/>
|
/>
|
||||||
</p:tab>
|
</p:tab>
|
||||||
|
<!-- -->
|
||||||
|
<p:tab id="tabImportExport" title="Import/Export">
|
||||||
|
<h:outputText value="For future implementation" />
|
||||||
|
</p:tab>
|
||||||
</p:tabView>
|
</p:tabView>
|
||||||
<h:form id="frmHome">
|
<h:form id="frmHome">
|
||||||
<p:commandButton id="doHome" value="Home"
|
<p:commandButton id="doHome" value="Home"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user