package de.onyxbits.tradetrax.pages.tools;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import org.apache.tapestry5.StreamResponse;
import org.apache.tapestry5.annotations.Component;
import org.apache.tapestry5.annotations.Persist;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.corelib.components.EventLink;
import org.apache.tapestry5.ioc.Messages;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.util.TextStreamResponse;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import de.onyxbits.tradetrax.entities.Stock;
import de.onyxbits.tradetrax.services.MoneyRepresentation;
import de.onyxbits.tradetrax.services.SettingsStore;
/**
* Prints a simple pricelist consisting of asset name, variant (if available)
* and expected retail price (stock.sellprice). Only "on hand" items (aquired,
* but not liquidated) are listed. Since the list is meant to be shared with
* buyers via email or other text only communication channels, unitcounts are
* not included (wouldn't be meaningful to tell buyer A and B that X units are
* available if they buy independently).
*
* @author patrick
*
*/
public class Pricelist {
@Property
@Persist
private String pricelist;
@Inject
private Session session;
@Inject
private SettingsStore settingsStore;
@Inject
private MoneyRepresentation moneyRepresentation;
@Inject
private Messages messages;
@Component(id = "print")
private EventLink print;
public StreamResponse onPrint() {
if (pricelist == null) {
// e.g. because the user had this bookmarked
setupRender();
}
return new TextStreamResponse("text/plain", pricelist);
}
public void setupRender() {
@SuppressWarnings("unchecked")
List<Stock> lst = session.createCriteria(Stock.class).add(Restrictions.isNotNull("acquired"))
.add(Restrictions.isNull("liquidated")).add(Restrictions.ge("unitCount", 1))
.add(Restrictions.gt("sellPrice", 0l)).list();
if (lst.size() == 0) {
pricelist = messages.get("empty");
return;
}
HashMap<String, Long> seen = new HashMap<String, Long>();
StringBuilder sb = new StringBuilder();
int longestEntry = 0;
int longestPrice = 0;
for (Stock stock : lst) {
sb.setLength(0);
sb.append(stock.getName().getLabel());
if (stock.getVariant() != null) {
sb.append(", ");
sb.append(stock.getVariant().getLabel());
}
// Figure out how much padding we need
if (sb.length() > longestEntry) {
longestEntry = sb.length();
}
String tmp = moneyRepresentation.databaseToUser(stock.getSellPrice(), false, true);
if (tmp.length() > longestPrice) {
longestPrice = tmp.length();
}
// It is entirely possible that we have the same asset with multiple sell
// prices in the database. In that case, we should only list it once and
// with the highest offer.
Long price = seen.get(sb.toString());
if (price == null) {
seen.put(sb.toString(), stock.getSellPrice());
}
else {
if (stock.getSellPrice() > price.longValue()) {
seen.put(sb.toString(), stock.getSellPrice());
}
}
}
sb.setLength(0);
String[] keys = seen.keySet().toArray(new String[0]);
Arrays.sort(keys);
for (String key : keys) {
String tmp = moneyRepresentation.databaseToUser(seen.get(key), false, true);
int pad = longestEntry - key.length() + longestPrice - tmp.length() + 2;
sb.append(key);
for (int i = 0; i < pad; i++) {
sb.append(" ");
}
sb.append(tmp);
sb.append("\n");
}
pricelist = sb.toString();
}
}