parent
349fec17ac
commit
3fd7bdb842
14 changed files with 896 additions and 17 deletions
@ -0,0 +1,121 @@ |
||||
CREATE TABLE keylookup ( |
||||
id INTEGER NOT NULL, |
||||
word TEXT, |
||||
item TEXT, |
||||
ingkey TEXT, |
||||
count INTEGER, |
||||
PRIMARY KEY (id) |
||||
); |
||||
CREATE TABLE info ( |
||||
version_super INTEGER, |
||||
version_major INTEGER, |
||||
version_minor INTEGER, |
||||
last_access INTEGER, |
||||
rowid INTEGER NOT NULL, |
||||
PRIMARY KEY (rowid) |
||||
); |
||||
CREATE TABLE recipe ( |
||||
id INTEGER NOT NULL, |
||||
title TEXT, |
||||
instructions TEXT, |
||||
modifications TEXT, |
||||
cuisine TEXT, |
||||
rating INTEGER, |
||||
description TEXT, |
||||
source TEXT, |
||||
preptime INTEGER, |
||||
cooktime INTEGER, |
||||
servings FLOAT, |
||||
yields FLOAT, |
||||
yield_unit VARCHAR(32), |
||||
image BLOB, |
||||
thumb BLOB, |
||||
deleted BOOLEAN, |
||||
recipe_hash VARCHAR(32), |
||||
ingredient_hash VARCHAR(32), |
||||
link TEXT, |
||||
last_modified INTEGER, |
||||
PRIMARY KEY (id), |
||||
CHECK (deleted IN (0, 1)) |
||||
); |
||||
CREATE TABLE plugin_info ( |
||||
plugin TEXT, |
||||
id INTEGER NOT NULL, |
||||
version_super INTEGER, |
||||
version_major INTEGER, |
||||
version_minor INTEGER, |
||||
plugin_version VARCHAR(32), |
||||
PRIMARY KEY (id) |
||||
); |
||||
CREATE TABLE categories ( |
||||
id INTEGER NOT NULL, |
||||
recipe_id INTEGER, |
||||
category TEXT, |
||||
PRIMARY KEY (id), |
||||
FOREIGN KEY(recipe_id) REFERENCES recipe (id) |
||||
); |
||||
CREATE TABLE ingredients ( |
||||
id INTEGER NOT NULL, |
||||
recipe_id INTEGER, |
||||
refid INTEGER, |
||||
unit TEXT, |
||||
amount FLOAT, |
||||
rangeamount FLOAT, |
||||
item TEXT, |
||||
ingkey TEXT, |
||||
optional BOOLEAN, |
||||
shopoptional INTEGER, |
||||
inggroup TEXT, |
||||
position INTEGER, |
||||
deleted BOOLEAN, |
||||
PRIMARY KEY (id), |
||||
CHECK (deleted IN (0, 1)), |
||||
FOREIGN KEY(recipe_id) REFERENCES recipe (id), |
||||
FOREIGN KEY(refid) REFERENCES recipe (id), |
||||
CHECK (optional IN (0, 1)) |
||||
); |
||||
CREATE TABLE IF NOT EXISTS "pantry" ( |
||||
id INTEGER NOT NULL, |
||||
ingkey TEXT(32), |
||||
pantry BOOLEAN, |
||||
PRIMARY KEY (id), |
||||
CHECK (pantry IN (0, 1)) |
||||
); |
||||
CREATE TABLE unitdict ( |
||||
id INTEGER NOT NULL, |
||||
ukey VARCHAR(150), |
||||
value VARCHAR(150), |
||||
PRIMARY KEY (id) |
||||
); |
||||
CREATE TABLE crossunitdict ( |
||||
id INTEGER NOT NULL, |
||||
cukey VARCHAR(150), |
||||
value VARCHAR(150), |
||||
PRIMARY KEY (id) |
||||
); |
||||
CREATE TABLE density ( |
||||
id INTEGER NOT NULL, |
||||
dkey VARCHAR(150), |
||||
value VARCHAR(150), |
||||
PRIMARY KEY (id) |
||||
); |
||||
CREATE TABLE shopcatsorder ( |
||||
id INTEGER NOT NULL, |
||||
shopcategory TEXT(32), |
||||
position INTEGER, |
||||
PRIMARY KEY (id) |
||||
); |
||||
CREATE TABLE convtable ( |
||||
id INTEGER NOT NULL, |
||||
ckey VARCHAR(150), |
||||
value VARCHAR(150), |
||||
PRIMARY KEY (id) |
||||
); |
||||
CREATE TABLE IF NOT EXISTS "shopcats" ( |
||||
id INTEGER NOT NULL, |
||||
ingkey TEXT(32), |
||||
shopcategory TEXT, |
||||
position INTEGER, |
||||
PRIMARY KEY (id) |
||||
); |
||||
CREATE TABLE IF NOT EXISTS "recipe_ingredients" ("Recipe_id" integer not null, "ingredientHash_id" integer not null, unique ("ingredientHash_id")); |
@ -0,0 +1,161 @@ |
||||
package com.mousetech.gourmetj; |
||||
|
||||
import com.mousetech.gourmetj.utils.IngredientDigester; |
||||
import com.mousetech.gourmetj.utils.IngredientDigester.IngredientAmountFormat; |
||||
|
||||
public class ShopIngredient implements Comparable<Object> { |
||||
/** |
||||
* Constructor. |
||||
* |
||||
* @param shopCat |
||||
* @param ingkey |
||||
*/ |
||||
public ShopIngredient( String shopCat, String item, |
||||
String ingkey) { |
||||
this.shopCat = shopCat; |
||||
this.ingkey = ingkey; |
||||
} |
||||
|
||||
/** |
||||
* Constructor. |
||||
* |
||||
* @param amount |
||||
* @param unit |
||||
* @param item |
||||
* @param ingkey |
||||
* @param shopCat |
||||
*/ |
||||
public ShopIngredient( double amount, String unit, |
||||
String item, String ingkey, |
||||
String shopCat) { |
||||
this.amount = amount; |
||||
this.unit = unit; |
||||
this.item = item; |
||||
this.ingkey = ingkey; |
||||
this.shopCat = shopCat; |
||||
} |
||||
|
||||
private String shopCat; |
||||
|
||||
/** |
||||
* @return the shopCat |
||||
*/ |
||||
public String getShopCat() { |
||||
return shopCat; |
||||
} |
||||
|
||||
/** |
||||
* @param shopCat the shopCat to set |
||||
*/ |
||||
public void setShopCat(String shopCat) { |
||||
this.shopCat = shopCat; |
||||
} |
||||
|
||||
/** |
||||
* @return the ingkey |
||||
*/ |
||||
public String getIngkey() { |
||||
return ingkey; |
||||
} |
||||
|
||||
/** |
||||
* @param ingkey the ingkey to set |
||||
*/ |
||||
public void setIngkey(String ingkey) { |
||||
this.ingkey = ingkey; |
||||
} |
||||
|
||||
/** |
||||
* @return the amount |
||||
*/ |
||||
public double getAmount() { |
||||
return amount; |
||||
} |
||||
|
||||
/** |
||||
* @param amount the amount to set |
||||
*/ |
||||
public void setAmount(double amount) { |
||||
this.amount = amount; |
||||
} |
||||
|
||||
/** |
||||
* @return the displayAmount |
||||
*/ |
||||
public String getDisplayAmount() { |
||||
return IngredientDigester.displayAmount( |
||||
IngredientAmountFormat.IA_TEXT, this.getAmount(), |
||||
null); |
||||
} |
||||
|
||||
/** |
||||
* @return the unit |
||||
*/ |
||||
public String getUnit() { |
||||
return unit; |
||||
} |
||||
|
||||
/** |
||||
* @param unit the unit to set |
||||
*/ |
||||
public void setUnit(String unit) { |
||||
this.unit = unit; |
||||
} |
||||
|
||||
private String item; |
||||
|
||||
/** |
||||
* @return the item |
||||
*/ |
||||
public String getItem() { |
||||
return item; |
||||
} |
||||
|
||||
private String ingkey; |
||||
private double amount; |
||||
private String displayAmount; |
||||
private String unit; |
||||
|
||||
@Override |
||||
public int compareTo(Object o) { |
||||
if ((o == null) || !(o instanceof ShopIngredient)) { |
||||
throw new RuntimeException( |
||||
"Invalid shipIngredient comparison"); |
||||
} |
||||
ShopIngredient o1 = (ShopIngredient) o; |
||||
int i = relate(this.getItem(), o1.getItem()); |
||||
if (i != 0) { |
||||
return i; |
||||
} |
||||
i = relate(this.getShopCat(), o1.getShopCat()); |
||||
if (i != 0) { |
||||
return i; |
||||
} |
||||
// TODO: normalize case, singular/plural/abbreviations
|
||||
i = relate(this.getUnit(), o1.getUnit()); |
||||
if (i != 0) { |
||||
return i; |
||||
} |
||||
return i; // ZERO
|
||||
} |
||||
|
||||
private int relate(String item2, String item3) { |
||||
if ((item2 == null) && (item3 == null)) { |
||||
return 0; |
||||
} |
||||
if (item2 == null) { |
||||
return -1; |
||||
} |
||||
if (item3 == null) { |
||||
return 1; |
||||
} |
||||
return item2.compareTo(item3); |
||||
} |
||||
|
||||
@Override |
||||
public String toString() { |
||||
return this.getAmount() + " " + this.getUnit() + " " |
||||
+ this.getItem() + " " + this.getIngkey() + " " |
||||
+ this.getShopCat(); |
||||
} |
||||
} |
@ -0,0 +1,213 @@ |
||||
package com.mousetech.gourmetj; |
||||
|
||||
import java.io.Serializable; |
||||
import java.util.ArrayList; |
||||
import java.util.Comparator; |
||||
import java.util.List; |
||||
|
||||
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.event.ReorderEvent; |
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
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; |
||||
|
||||
@Named |
||||
@ViewScoped |
||||
public class ShoppingListBean implements Serializable { |
||||
|
||||
/** |
||||
* Serial version for session save/restore |
||||
*/ |
||||
private static final long serialVersionUID = |
||||
7449440266704831598L; |
||||
|
||||
/* Logger */ |
||||
|
||||
@SuppressWarnings("unused") |
||||
private static final Logger log = |
||||
LoggerFactory.getLogger(ShoppingListBean.class); |
||||
|
||||
@Inject |
||||
private UserSession userSession; |
||||
|
||||
private List<ShopIngredient> siList; |
||||
|
||||
// private List<ShopIngredient> ingredientList;
|
||||
|
||||
@PostConstruct |
||||
public void init() { |
||||
// Load up details on recipes
|
||||
this.siList = new ArrayList<ShopIngredient>(30); |
||||
buildMaps(); |
||||
} |
||||
|
||||
public List<Recipe> getRecipeList() { |
||||
return this.userSession.getShoppingList(); |
||||
} |
||||
|
||||
public List<ShopIngredient> getIngredientList() { |
||||
return this.siList; |
||||
} |
||||
|
||||
private void buildMaps() { |
||||
for (Recipe r : this.getRecipeList()) { |
||||
buildMapsFor(r); |
||||
} |
||||
// Now consolidate amounts and sort by
|
||||
// shopcat/item/ingkey
|
||||
optimizeIngredients(this.siList); |
||||
|
||||
this.siList.sort(new ShopclassComparator()); |
||||
} |
||||
|
||||
/** |
||||
* Run the ingredient list for the selected recipe and add |
||||
* them to siList |
||||
* |
||||
* @param r |
||||
* |
||||
* @see #buildMaps() |
||||
*/ |
||||
private void buildMapsFor(Recipe r) { |
||||
for (Ingredient ing : r.getIngredientHash()) { |
||||
String ingkey = ing.getIngkey(); |
||||
if (StringUtils.isBlank(ingkey)) { |
||||
continue; |
||||
} |
||||
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); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Sort ShopIngredient list, then optimize it by |
||||
* consolidating amounts where possible. |
||||
* |
||||
* @param victim List to optimize |
||||
* |
||||
* #TestedBy @see ShoppingListBeanTest |
||||
*/ |
||||
static void optimizeIngredients( |
||||
List<ShopIngredient> victim) { |
||||
victim.sort(null); |
||||
for (int i = 0; i < (victim.size() - 1); i++) { |
||||
ShopIngredient si = victim.get(i); |
||||
ShopIngredient si2 = victim.get(i + 1); |
||||
if (si.compareTo(si2) == 0) { |
||||
si.setAmount(si.getAmount() + si2.getAmount()); |
||||
victim.remove(si2); // reduces size()
|
||||
} |
||||
} |
||||
} |
||||
|
||||
class ShopclassComparator |
||||
implements Comparator<ShopIngredient> { |
||||
|
||||
@Override |
||||
public int compare(ShopIngredient ing1, |
||||
ShopIngredient ing2) { |
||||
int i = 0; |
||||
i = relate(ing1.getShopCat(), ing2.getShopCat()); |
||||
if (i != 0) { |
||||
return i; |
||||
} |
||||
i = relate(ing1.getItem(), ing2.getItem()); |
||||
if (i != 0) { |
||||
return i; |
||||
} |
||||
i = relate(ing1.getIngkey(), ing2.getIngkey()); |
||||
if (i != 0) { |
||||
return i; |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
private int relate(String item2, String item3) { |
||||
if ((item2 == null) && (item3 == null)) { |
||||
return 0; |
||||
} |
||||
if (item2 == null) { |
||||
return -1; |
||||
} |
||||
if (item3 == null) { |
||||
return 1; |
||||
} |
||||
return item2.compareTo(item3); |
||||
} |
||||
} |
||||
|
||||
private List<Shopcat> shopcatList; |
||||
|
||||
public List<Shopcat> getShopcatList() { |
||||
if (shopcatList == null) { |
||||
shopcatList = loadShopcatList(); |
||||
} |
||||
return shopcatList; |
||||
} |
||||
|
||||
@Inject |
||||
ShopcatRepository shopcatRepository; |
||||
|
||||
private List<Shopcat> loadShopcatList() { |
||||
return shopcatRepository |
||||
.findAllByOrderByShopcategoryAsc(); |
||||
} |
||||
|
||||
private Shopcat xeditShopcat = new Shopcat(); |
||||
|
||||
private String oldShopcategoryName; |
||||
|
||||
/** |
||||
* @return the editShopcat |
||||
*/ |
||||
public Shopcat getEditShopcat() { |
||||
return xeditShopcat; |
||||
} |
||||
|
||||
public void doEditShopcat(int scId) { |
||||
xeditShopcat = null; |
||||
final List<Shopcat> scl = getShopcatList(); |
||||
for (Shopcat sc : scl) { |
||||
if (sc.getId() == scId) { |
||||
xeditShopcat = sc; |
||||
this.oldShopcategoryName = sc.getShopcategory(); |
||||
if (sc.getPosition() == null) { |
||||
sc.setPosition(0); |
||||
} |
||||
return; |
||||
} |
||||
} |
||||
log.error("SHOPCAT " + scId + " NOT FOUND"); |
||||
} |
||||
|
||||
public void ajaxOnClickShopcatIngkey() { |
||||
// Saves 1 shopcat/ingkey
|
||||
this.shopcatRepository.save(xeditShopcat); |
||||
this.shopcatList = null; |
||||
} |
||||
|
||||
/** |
||||
* Updates all ingredient keys for shopcat name-change. |
||||
* Note that once done, this cannot be undone! |
||||
*/ |
||||
public void ajaxOnClickShopcat() { |
||||
this.shopcatRepository.UpdateShopcats( |
||||
this.oldShopcategoryName, xeditShopcat.getShopcategory()); |
||||
this.shopcatList = null; |
||||
} |
||||
} |
@ -0,0 +1,68 @@ |
||||
<!DOCTYPE html> |
||||
<html xmlns="http://www.w3.org/1999/xhtml" |
||||
xmlns:h="http://xmlns.jcp.org/jsf/html" |
||||
xmlns:f="http://xmlns.jcp.org/jsf/core" |
||||
xmlns:ui="http://java.sun.com/jsf/facelets" |
||||
xmlns:p="http://primefaces.org/ui" |
||||
> |
||||
<h:head> |
||||
<title>Shopping Category</title> |
||||
<style type="text/css"> |
||||
html { |
||||
font-size: 14px; |
||||
} |
||||
</style> |
||||
</h:head> |
||||
<h:body> |
||||
<ui:component> |
||||
<h:form id="frmShopcat"> |
||||
<p:panelGrid columns="1"> |
||||
<p:dataTable id="tblShopcats" |
||||
style="width: 600px" |
||||
value="#{shoppingListBean.shopcatList}" |
||||
sortBy="#{item.shopCat}" var="item" |
||||
> |
||||
<p:headerRow> |
||||
<p:column colspan="4"> |
||||
<h:outputText value="#{item.shopCat}" /> |
||||
</p:column> |
||||
</p:headerRow> |
||||
</p:dataTable> |
||||
<div>Ingredient key: |
||||
#{editShopcatBean.ingkey}</div> |
||||
<p:outputLabel for="@next" |
||||
value="Category Name" |
||||
/> |
||||
<p:inputText id="ctlShopcat" |
||||
value="#{editShopcatBean.shopcatName}" |
||||
> |
||||
</p:inputText> |
||||
<h:outputText value="suggestion:" /> |
||||
<p:selectOneMenu id="ctlShopcatMenu" |
||||
value="#{editShopcatBean.shopcatSuggestion}" |
||||
> |
||||
<f:selectItems |
||||
value="#{editShopcatBean.shopcatSuggestionList}" |
||||
/> |
||||
<p:ajax event="change" |
||||
listener="#{editShopcatBean.ajaxShopcatSuggest}" |
||||
update="ctlShopcat" |
||||
/> |
||||
</p:selectOneMenu> |
||||
<p:panelGrid columns="2" style="width: 100%"> |
||||
<p:commandButton id="scDlgOK" value="OK" |
||||
style="width: 6em" |
||||
action="#{recipeDetailBean.doUpdateShopcat}" |
||||
update="form1:tabGroupClient:ingredientTable" |
||||
oncomplete="PF('editShopcatDlg').hide()" |
||||
/> |
||||
<p:commandButton id="scDlgCan" |
||||
value="Cancel" style="width: 6em" |
||||
onclick="PF('editShopcatDlg').hide()" |
||||
/> |
||||
</p:panelGrid> |
||||
</p:panelGrid> |
||||
</h:form> |
||||
</ui:component> |
||||
</h:body> |
||||
</html> |
@ -0,0 +1,198 @@ |
||||
<?xml version="1.0"?> |
||||
<ui:composition template="/WEB-INF/layout/layout.xhtml" |
||||
xmlns:h="http://xmlns.jcp.org/jsf/html" |
||||
xmlns:f="http://xmlns.jcp.org/jsf/core" |
||||
xmlns:ui="http://java.sun.com/jsf/facelets" |
||||
xmlns:p="http://primefaces.org/ui" |
||||
xmlns:c="http://xmlns.jcp.org/jstl" |
||||
> |
||||
<ui:define name="title">Gourmet Recipe Manager - Shopping</ui:define> |
||||
<ui:define name="content"> |
||||
<style> |
||||
.recipeTitle { |
||||
font-size: larger; |
||||
font-weight: bold; |
||||
} |
||||
|
||||
.subtitle { |
||||
font-size: large; |
||||
font-weight: bold; |
||||
} |
||||
|
||||
.ui-panelgrid-cell { |
||||
border-width: 0; |
||||
border-style: none; |
||||
} |
||||
</style> |
||||
<h:messages /> |
||||
<h:form id="form1"> |
||||
<p:dataTable id="tblRecipes" style="width: 600px" |
||||
value="#{shoppingListBean.recipeList}" var="item" |
||||
> |
||||
<p:column headerText="Recipe"> |
||||
<h:outputText value="#{item.title}" /> |
||||
</p:column> |
||||
</p:dataTable> |
||||
<!-- ====== Ingredients ============================ --> |
||||
<p:column id="ingredientsc" |
||||
style="width: 25%; vertical-align: top;" |
||||
> |
||||
<p:dataTable id="tblShopIngredients" |
||||
style="width: 600px; margin-top: 10px" |
||||
value="#{shoppingListBean.ingredientList}" |
||||
sortBy="#{item.shopCat}" var="item" |
||||
> |
||||
<f:facet name="header"> |
||||
<h:outputText styleClass="subtitle" |
||||
value="Ingredients" |
||||
/> |
||||
</f:facet> |
||||
<p:headerRow> |
||||
<p:column colspan="4"> |
||||
<h:outputText value="#{item.shopCat}" /> |
||||
</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" |
||||
> |
||||
<h:outputText |
||||
value="#{item.displayAmount}" |
||||
/> |
||||
</p:column> |
||||
<p:column label="Units" style="width: 5em"> |
||||
<h:outputText value="#{item.unit}" /> |
||||
</p:column> |
||||
<p:column label="Item" style="width: 20em"> |
||||
<h:outputText value="#{item.item}" /> |
||||
</p:column> |
||||
</p:dataTable> |
||||
</p:column> |
||||
<p:commandButton id="doHome" value="Home" |
||||
icon="ui-icon-home" ajax="false" immediate="true" |
||||
action="main.jsf" |
||||
/> |
||||
<p:dataTable id="tblShopcats" style="width: 300px" |
||||
value="#{shoppingListBean.shopcatList}" |
||||
sortBy="#{item.shopcategory}" var="item" |
||||
> |
||||
<f:facet name="header"> |
||||
<h:outputText |
||||
value="Ingredient Keys/Shopping Categories" |
||||
/> |
||||
</f:facet> |
||||
<p:headerRow> |
||||
<p:column> |
||||
<h:outputText id="ctlCatname" |
||||
value="#{item.shopcategory}" |
||||
/> |
||||
</p:column> |
||||
<p:column style="width: 5em"> |
||||
<p:commandButton id="ctlEditCat" |
||||
value="Rename" |
||||
action="#{shoppingListBean.doEditShopcat(item.id)}" |
||||
onclick="PF('dlgEditShopcat').show()" |
||||
update="frmEscat:pnlData" |
||||
/> |
||||
</p:column> |
||||
</p:headerRow> |
||||
<p:column> |
||||
<h:outputText value="#{item.ingkey}" |
||||
onclick="clickIngkeyName()" |
||||
/> |
||||
</p:column> |
||||
<p:column style="width: 5em"> |
||||
<p:commandButton id="ctlEditIngkey" |
||||
value="Move" |
||||
action="#{shoppingListBean.doEditShopcat(item.id)}" |
||||
onclick="PF('dlgEditIngkey').show()" |
||||
update="frmIngkey:pnlData" |
||||
/> |
||||
</p:column> |
||||
</p:dataTable> |
||||
</h:form> |
||||
<!-- --> |
||||
<h:form id="frmEscat"> |
||||
<p:dialog id="dlgEditShopcat" |
||||
widgetVar="dlgEditShopcat" |
||||
header="Edit/Rename Shopping Category" |
||||
closeOnEscape="true" |
||||
> |
||||
<p:panelGrid id="pnlData" columns="2" |
||||
styleClass="ui-panelgrid-blank" |
||||
> |
||||
<p:outputLabel for="@next" |
||||
value="Shopping Category" |
||||
/> |
||||
<p:inputText id="ctlDlgShopcatName" |
||||
label="Position" required="true" |
||||
value="#{shoppingListBean.editShopcat.shopcategory}" |
||||
/> |
||||
<p:outputLabel for="@next" value="Position" /> |
||||
<p:inputText id="ctlDlgShopcatPosition" |
||||
type="number" required="true" size="3" |
||||
value="#{shoppingListBean.editShopcat.position}" |
||||
/> |
||||
</p:panelGrid> |
||||
<p:panelGrid columns="2" style="width: 100%" |
||||
styleClass="ui-panelgrid-blank" |
||||
> |
||||
<p:commandButton id="scDlgOK" value="OK" |
||||
style="width: 6em" |
||||
action="#{shoppingListBean.ajaxOnClickShopcat}" |
||||
update="form1:tblShopcats" |
||||
process="@this pnlData" |
||||
oncomplete="PF('dlgEditShopcat').hide()" |
||||
/> |
||||
<p:commandButton id="scDlgCan" value="Cancel" |
||||
style="width: 6em" |
||||
onclick="PF('dlgEditShopcat').hide()" |
||||
/> |
||||
</p:panelGrid> |
||||
</p:dialog> |
||||
</h:form> |
||||
<!-- --> |
||||
<h:form id="frmIngkey"> |
||||
<p:dialog id="dlgEditIngkey" |
||||
widgetVar="dlgEditIngkey" |
||||
header="Edit/Rename Shopping Category for Ingredient Key" |
||||
closeOnEscape="true" |
||||
> |
||||
<p:panelGrid id="pnlData" columns="2" |
||||
styleClass="ui-panelgrid-blank" |
||||
> |
||||
<p:outputLabel for="@next" |
||||
value="Ingredient Key" |
||||
/> |
||||
<h:outputText id="ctlDlgIngKeyIngkey" |
||||
value="#{shoppingListBean.editShopcat.ingkey}" |
||||
/> |
||||
<p:outputLabel for="@next" |
||||
value="Shopping Category" |
||||
/> |
||||
<p:inputText id="ctlDlgIngkeyShopcatName" |
||||
label="Position" required="true" |
||||
value="#{shoppingListBean.editShopcat.shopcategory}" |
||||
/> |
||||
</p:panelGrid> |
||||
<p:panelGrid columns="2" style="width: 100%" |
||||
styleClass="ui-panelgrid-blank" |
||||
> |
||||
<p:commandButton id="ingkDlgOK" value="OK" |
||||
style="width: 6em" |
||||
action="#{shoppingListBean.ajaxOnClickShopcatIngkey}" |
||||
update="form1:tblShopcats" |
||||
process="@this pnlData" |
||||
oncomplete="PF('dlgEditIngkey').hide()" |
||||
/> |
||||
<p:commandButton id="ingkDlgCan" |
||||
value="Cancel" style="width: 6em" |
||||
onclick="PF('dlgEditIngkey').hide()" |
||||
/> |
||||
</p:panelGrid> |
||||
</p:dialog> |
||||
</h:form> |
||||
</ui:define> |
||||
</ui:composition> |
@ -0,0 +1,52 @@ |
||||
/** |
||||
* Copyright (C) 2022, Tim Holloway |
||||
* |
||||
* Date written: Jan 12, 2022 |
||||
* Author: Tim Holloway <timh@mousetech.com> |
||||
*/ |
||||
package com.mousetech.gourmetj; |
||||
|
||||
import static org.junit.jupiter.api.Assertions.*; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
import org.junit.jupiter.api.BeforeAll; |
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import com.mousetech.gourmetj.ShopIngredient; |
||||
import com.mousetech.gourmetj.persistence.model.Shopcat; |
||||
|
||||
/** |
||||
* @author timh |
||||
* @since Jan 12, 2022 |
||||
*/ |
||||
class ShoppingListBeanTest { |
||||
|
||||
static List<ShopIngredient> testList; |
||||
|
||||
/** |
||||
* @throws java.lang.Exception |
||||
*/ |
||||
@BeforeAll |
||||
static void setUpBeforeClass() throws Exception { |
||||
testList = new ArrayList<ShopIngredient>(); |
||||
testList.add(new ShopIngredient(2.0d, "cup", |
||||
"sugar", "sugar", "baking")); |
||||
testList.add(new ShopIngredient(1.5, "tsp", |
||||
"salt", "salt", "condiments")); |
||||
testList.add(new ShopIngredient(0.5, "tsp", |
||||
"pepper", "pepper", "condiments")); |
||||
testList.add(new ShopIngredient(2.0d, "cup", |
||||
"milk", "milk", "dairy")); |
||||
testList.add(new ShopIngredient(0.75d, "cup", |
||||
"sugar", "sugar", "baking")); |
||||
} |
||||
|
||||
@Test |
||||
void test() { |
||||
ShoppingListBean.optimizeIngredients(testList); |
||||
assertEquals(4, testList.size()); |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue