Skip to content

Commit

Permalink
ShoppingList: Check in of wines
Browse files Browse the repository at this point in the history
Check in specifing the wine cellar:
- existing wines
- new wines

Fully tested by hand, JUnit tests only changed so the run. New features
are not yet unit tested. Tomorrow.

Fixes #26

Signed-off-by: Daniel Ritz <[email protected]>
  • Loading branch information
dr-itz committed Jan 19, 2011
1 parent 128d96c commit 2b946d5
Show file tree
Hide file tree
Showing 22 changed files with 522 additions and 79 deletions.
10 changes: 10 additions & 0 deletions db/migrate.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,13 @@ CREATE TABLE IF NOT EXISTS `shoppinglist` (
ALTER TABLE `shoppinglist`
ADD CONSTRAINT `shoppinglist_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;


2011-01-18
----------

ALTER TABLE `shoppinglist`
CHANGE `name` `name` VARCHAR(50) NULL,
ADD `wine_id` INT NULL AFTER `user_id`,
ADD INDEX (`wine_id`),
ADD FOREIGN KEY (`wine_id`) REFERENCES `wines` (`id`)
ON DELETE RESTRICT ON UPDATE CASCADE ;
8 changes: 5 additions & 3 deletions db/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,16 @@ DROP TABLE IF EXISTS `shoppinglist`;
CREATE TABLE IF NOT EXISTS `shoppinglist` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`name` varchar(50) NOT NULL,
`wine_id` int(11) DEFAULT NULL,
`name` varchar(50) DEFAULT NULL,
`producer` varchar(50) DEFAULT NULL,
`year` int(11) DEFAULT NULL,
`quantity` int(11) NOT NULL,
`store` varchar(50) DEFAULT NULL,
`bottle_size` smallint(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`)
KEY `user_id` (`user_id`),
KEY `wine_id` (`wine_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- --------------------------------------------------------
Expand Down Expand Up @@ -133,8 +135,8 @@ CREATE TABLE IF NOT EXISTS `wine_years` (
-- Constraints for dumped tables
--
ALTER TABLE `shoppinglist`
ADD CONSTRAINT `shoppinglist_ibfk_2` FOREIGN KEY (`wine_id`) REFERENCES `wines` (`id`) ON UPDATE CASCADE,
ADD CONSTRAINT `shoppinglist_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;

--
-- Constraints for table `winecellars`
--
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/ch/sfdr/lacantina/dao/ICellarEntryDAO.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,17 @@ List<CellarEntry> getCellarEntries(int winecellarId, int userId,
CellarEntry getCellarEntry(int id, int userId)
throws DAOException;

/**
* reads a cellar entry by wine cellar ID, wine id and year
* @param cellarId ID of the wine cellar
* @param wineId ID of the wine
* @param year year of the wine
* @return cellar entry if found, otherwise null
* @throws DAOException
*/
CellarEntry getCellarEntry(int cellarId, int wineId, int year)
throws DAOException;

/**
* stores a cellar entry (either insert or update)
* @param ce the cellar entry
Expand Down
33 changes: 31 additions & 2 deletions src/main/java/ch/sfdr/lacantina/dao/db/AbstractDAO.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

Expand Down Expand Up @@ -217,24 +218,52 @@ protected List<T> getPagedRowList(String countQuery, String query,
/**
* executes a statement without results
* @param query the query string
* @param autoInc if true, returns the generated autoinc value
* @param bind the bind params
* @throws DAOException
*/
protected void executeUpdateStatement(String query, Object... bind)
protected int executeUpdateStatement(String query, boolean autoInc,
Object... bind)
throws DAOException
{
int ret = 0;
PreparedStatement stmt = null;
try {
stmt = conn.prepareStatement(query);
stmt = conn.prepareStatement(query,
autoInc ?
Statement.RETURN_GENERATED_KEYS :
Statement.NO_GENERATED_KEYS);
fillStatement(stmt, bind);
stmt.executeUpdate();

if (autoInc) {
ResultSet rs = stmt.getGeneratedKeys();
if (rs.next())
ret = rs.getInt(1);
rs.close();
}
} catch (SQLException e) {
throw new DAOException(e);
} finally {
DBConnection.closeStatement(stmt);
}
return ret;
}


/**
* executes a statement without results
* @param query the query string
* @param bind the bind params
* @throws DAOException
*/
protected void executeUpdateStatement(String query, Object... bind)
throws DAOException
{
executeUpdateStatement(query, false, bind);
}


/**
* returns a new SortPair
* @param key
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/ch/sfdr/lacantina/dao/db/DbCellarEntryDAO.java
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,18 @@ public CellarEntry getCellarEntry(int id, int userId)
id, userId);
}

/*
* @see ch.sfdr.lacantina.dao.ICellarEntryDAO#getCellarEntry(int)
*/
public CellarEntry getCellarEntry(int cellarId, int wineId, int year)
throws DAOException
{
return getSingleRow(
CELLARENTRY_SELECT +
"WHERE y.winecellar_id = ? AND y.wine_id = ? AND y.year = ?",
cellarId, wineId, year);
}

/*
* @see ch.sfdr.lacantina.dao.ICellarEntryDAO#getCellarEntries(int, int)
*/
Expand Down
11 changes: 7 additions & 4 deletions src/main/java/ch/sfdr/lacantina/dao/db/DbShoppingListDAO.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public DbShoppingListDAO(Connection conn)
* Query used to read shopping items
*/
private static final String USER_SELECT =
"SELECT id, user_id, name, producer, year, store, bottle_size, quantity " +
"SELECT id, user_id, wine_id, name, producer, year, store, bottle_size, quantity " +
"FROM shoppinglist ";

/**
Expand All @@ -54,6 +54,9 @@ public ShoppingItem readRow(ResultSet rs)
int n = 1;
i.setId(rs.getInt(n++));
i.setUserId(rs.getInt(n++));
i.setWineId(rs.getInt(n++));
if (rs.wasNull())
i.setWineId(null);
i.setName(rs.getString(n++));
i.setProducer(rs.getString(n++));
i.setYear(rs.getInt(n++));
Expand Down Expand Up @@ -103,10 +106,10 @@ public void storeShoppingItem(ShoppingItem w)
if (w.getId() == 0) {
executeUpdateStatement(
"INSERT INTO shoppinglist" +
" (user_id, name, producer, year, quantity, store," +
" (user_id, wine_id, name, producer, year, quantity, store," +
" bottle_size) " +
"VALUES (?, ?, ?, ?, ?, ?, ?)",
w.getUserId(), w.getName(), w.getProducer(), w.getYear(),
"VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
w.getUserId(), w.getWineId(), w.getName(), w.getProducer(), w.getYear(),
w.getQuantity(), w.getStore(), w.getBottleSize());
} else {
executeUpdateStatement(
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/ch/sfdr/lacantina/dao/db/DbWineDAO.java
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,14 @@ public void storeWine(Wine w)
throws DAOException
{
if (w.getId() == 0) {
executeUpdateStatement(
int id = executeUpdateStatement(
"INSERT INTO wines" +
" (user_id, name, producer, country, region, description," +
" bottle_size) " +
"VALUES (?, ?, ?, ?, ?, ?, ?)",
"VALUES (?, ?, ?, ?, ?, ?, ?)", true,
w.getUserId(), w.getName(), w.getProducer(), w.getCountry(),
w.getRegion(), w.getDescription(), w.getBottleSize());
w.setId(id);
} else {
executeUpdateStatement(
"UPDATE wines SET" +
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/ch/sfdr/lacantina/dao/objects/ShoppingItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public class ShoppingItem
{
private int id;
private int userId;
private Integer wineId;
private String name;
private String producer;
private Integer year;
Expand Down Expand Up @@ -47,6 +48,22 @@ public void setUserId(int userId)
this.userId = userId;
}

/**
* @return the wineId
*/
public Integer getWineId()
{
return wineId;
}

/**
* @param wineId the wineId to set
*/
public void setWineId(Integer wineId)
{
this.wineId = wineId;
}

/**
* @return the name
*/
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/ch/sfdr/lacantina/dao/objects/Wine.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class Wine
private String country;
private String region;
private String description;
private short bottleSize;
private int bottleSize;

/**
* @return the id
Expand Down Expand Up @@ -130,7 +130,7 @@ public void setDescription(String description)
/**
* @return the bottleSize
*/
public short getBottleSize()
public int getBottleSize()
{
return bottleSize;
}
Expand All @@ -140,7 +140,7 @@ public short getBottleSize()
*/
public void setBottleSize(int bottleSize)
{
this.bottleSize = (short) bottleSize;
this.bottleSize = bottleSize;
}

/**
Expand Down
104 changes: 97 additions & 7 deletions src/main/java/ch/sfdr/lacantina/gui/ShoppingListAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public ActionForward doExecute(ActionMapping mapping, PagedForm pf,
int refId = form.getRefId();

form.reset(mapping, request);
ShoppingItem si = form.getWine();
ShoppingItem si = form.getItem();

Wine w = null;

Expand All @@ -79,35 +79,125 @@ public ActionForward doExecute(ActionMapping mapping, PagedForm pf,
si.setName(w.getName());
si.setProducer(w.getProducer());
si.setBottleSize(w.getBottleSize());
si.setWineId(w.getId());
}

return returnInputForward(form, mapping, request);
}

IShoppingListDAO dao = conn.getShoppingListDAO();

/*
* "check-in" handling
*/
if (ShoppingListForm.ACTION_CHEKIN_FORM.equals(action)) {
int id = form.getItem().getId();
form.reset(mapping, request);

ShoppingItem item = dao.getShoppingItem(id);
form.setItem(item);

if (item.getWineId() != null) {
IWineDAO wdao = conn.getWineDAO();
Wine w = wdao.getWine(item.getWineId());
form.setWine(w);
} else {
Wine w = form.getWine();
w.setName(item.getName());
w.setProducer(item.getProducer());
w.setBottleSize(item.getBottleSize());
}

request.setAttribute("checkinForm", "yesSir");
return returnInputForward(form, conn, mapping, request);
}

if (ShoppingListForm.ACTION_CHEKIN.equals(action)) {
Wine w = form.getWine();
ShoppingItem item = form.getItem();
if (item.getWineId() != null)
w.setId(item.getWineId());

boolean wineCreated = false;
if (w.getId() == 0) {
w.setUserId(SecManager.getUserId(request));

IWineDAO wdao = conn.getWineDAO();
wdao.storeWine(w);
wineCreated = true;
}

ICellarEntryDAO ceDao = conn.getCellarEntryDAO();

// search wine cellar entry
CellarEntry ce = null;
if (!wineCreated) {
ce = ceDao.getCellarEntry(form.getWineCellarId(), w.getId(),
item.getYear());
// if found: add quantity
if (ce != null)
ce.setQuantity(ce.getQuantity() + item.getQuantity());
}
if (ce == null) {
// not found: create new
ce = new CellarEntry();
ce.setWine(w);
ce.setWinecellarId(form.getWineCellarId());
ce.setYear(item.getYear());
ce.setQuantity(item.getQuantity());
}
// save wine cellar entry
ceDao.storeCellarEntry(ce);

// delete shopping item
try {
dao.deleteShoppingItem(form.getItem().getId());
} catch (DAOException e) {
attachSingleErrorMessage(mapping, request,
"shoppinglist.delete.failed");
}
}


/*
* "normal" handling
*/
if (BaseForm.ACTION_FORM.equals(action)) {
if (form.getWine().getId() != 0) {
ShoppingItem item = dao.getShoppingItem(form.getWine().getId());
form.setWine(item);
if (form.getItem().getId() != 0) {
ShoppingItem item = dao.getShoppingItem(form.getItem().getId());
form.setItem(item);
}
return returnInputForward(form, mapping, request);
}

if (BaseForm.ACTION_MODIFY.equals(action)) {
try {
ShoppingItem si = form.getWine();
ShoppingItem si = form.getItem();

/*
* copy-paste name/producer/bottle size.
* stupid, but solves sorting issues w/o touch much code.
*/
if (si.getWineId() != null) {
IWineDAO wdao = conn.getWineDAO();
Wine w = wdao.getWine(si.getWineId());
si.setName(w.getName());
si.setProducer(w.getProducer());
si.setBottleSize(w.getBottleSize());
}

si.setUserId(SecManager.getUserId(request));

dao.storeShoppingItem(si);
} catch (DAOException e) {
attachSingleErrorMessage(mapping, request,
"shoppinglist.update.failed");
}

} else if (BaseForm.ACTION_DELETE.equals(action)) {
if (form.getWine().getId() != 0) {
if (form.getItem().getId() != 0) {
try {
dao.deleteShoppingItem(form.getWine().getId());
dao.deleteShoppingItem(form.getItem().getId());
} catch (DAOException e) {
attachSingleErrorMessage(mapping, request,
"shoppinglist.delete.failed");
Expand Down
Loading

0 comments on commit 2b946d5

Please sign in to comment.