package de.onyxbits.tradetrax.pages.edit; import java.text.DateFormat; import java.text.ParseException; import java.util.Date; import java.util.List; import org.apache.tapestry5.alerts.AlertManager; import org.apache.tapestry5.alerts.Duration; import org.apache.tapestry5.alerts.Severity; import org.apache.tapestry5.annotations.Component; import org.apache.tapestry5.annotations.Import; import org.apache.tapestry5.annotations.InjectPage; import org.apache.tapestry5.annotations.Property; import org.apache.tapestry5.annotations.SessionAttribute; import org.apache.tapestry5.beaneditor.Validate; import org.apache.tapestry5.corelib.components.DateField; import org.apache.tapestry5.corelib.components.EventLink; import org.apache.tapestry5.corelib.components.Form; import org.apache.tapestry5.corelib.components.TextArea; import org.apache.tapestry5.corelib.components.TextField; import org.apache.tapestry5.hibernate.annotations.CommitAfter; import org.apache.tapestry5.ioc.Messages; import org.apache.tapestry5.ioc.annotations.Inject; import org.apache.tapestry5.services.javascript.JavaScriptSupport; import org.hibernate.Session; import de.onyxbits.tradetrax.components.Layout; import de.onyxbits.tradetrax.entities.Bookmark; import de.onyxbits.tradetrax.entities.IdentUtil; import de.onyxbits.tradetrax.entities.Stock; import de.onyxbits.tradetrax.pages.Index; import de.onyxbits.tradetrax.pages.tools.LedgerLog; import de.onyxbits.tradetrax.services.EventLogger; import de.onyxbits.tradetrax.services.MoneyRepresentation; import de.onyxbits.tradetrax.services.SettingsStore; @Import(library = "context:js/mousetrap.min.js") public class StockEditor { @Property private DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM); @SessionAttribute(Layout.FOCUSID) private long focusedStockId; @Component(id = "editForm") private Form editForm; @Property private long stockId; @Property private Stock stock; @Component(id = "units") private TextField unitsField; @Property private int units; @Component(id = "name") private TextField nameField; @Component(id="location") private TextField locationField; @Property @Validate("required,minlength=3") private String name; @Component(id = "variant") private TextField variantField; @Property private String variant; @Property private String location; @Component(id = "buyPrice") private TextField buyPriceField; @Property private String buyPrice; @Component(id = "sellPrice") private TextField sellPriceField; @Property private String sellPrice; @Component(id = "acquired") private DateField acquiredField; @Property private Date acquired; @Component(id = "liquidated") private DateField liquidatedField; @Property private Date liquidated; @Component(id = "comment") private TextArea commentField; @Component(id = "history") private EventLink history; @Property private String comment; @Inject private Session session; @Inject private AlertManager alertManager; @Inject private Messages messages; @Inject private EventLogger eventLogger; @Inject private MoneyRepresentation moneyRepresentation; @Inject private SettingsStore settingsStore; @InjectPage private LedgerLog ledgerLog; private boolean eventDelete; @Property private boolean splitable; @Property private boolean liquidateable; @Component(id = "bookmark") private EventLink bookmark; @Inject private JavaScriptSupport javaScriptSupport; public void onActivate(Long StockId) { this.stockId = StockId; } @CommitAfter protected void setupRender() { try { stock = (Stock) session.get(Stock.class, stockId); if (stock == null) { stock = new Stock(); stock.setAcquired(new Date()); stock.setUnitCount(1); if (stockId > 0) { alertManager.alert(Duration.SINGLE, Severity.INFO, messages.format("not-found", stockId)); Bookmark bm = (Bookmark) session.get(Bookmark.class, stockId); if (bm != null) { // This is a failsave in case something deletes stock but not // bookmarks. Normally we shouldn't get here. session.delete(bm); } } } if (stock.getName() != null) { name = stock.getName().getLabel(); } if (stock.getVariant() != null) { variant = stock.getVariant().getLabel(); } units = stock.getUnitCount(); // NOTE: fill buyPrice/sellPrice even if acquired/liquidated is null. The // user might have entered expected prices! buyPrice = moneyRepresentation.databaseToUser(stock.getBuyPrice(), true, false); sellPrice = moneyRepresentation.databaseToUser(stock.getSellPrice(), true, false); acquired = stock.getAcquired(); liquidated = stock.getLiquidated(); liquidateable = (liquidated == null && stock.getId() > 0); comment = stock.getComment(); splitable = stock.getUnitCount() > 1; location=stock.getLocation(); } catch (Exception e) { e.printStackTrace(); } } public List<String> onProvideCompletionsFromVariant(String partial) { return IdentUtil.suggestVariants(session, partial); } public List<String> onProvideCompletionsFromName(String partial) { return IdentUtil.suggestNames(session, partial); } protected Long onPassivate() { return stockId; } @CommitAfter protected StockEditor onBookmark(long id) { if (id < 1) { return this; } Bookmark bm = (Bookmark) session.get(Bookmark.class, id); if (bm == null) { alertManager.alert(Duration.SINGLE, Severity.INFO, messages.get("bookmark-set")); bm = new Bookmark(); bm.setId(id); session.save(bm); } else { alertManager.alert(Duration.SINGLE, Severity.INFO, messages.get("bookmark-deleted")); session.delete(bm); } return this; } protected void onSelectedFromDelete() { eventDelete = true; } protected void onSelectedFromSave() { eventDelete = false; } protected void onSelectedFromCreate() { eventDelete = false; } public void onValidateFromEditForm() { try { moneyRepresentation.userToDatabase(buyPrice, 1); } catch (ParseException e) { editForm.recordError(buyPriceField, messages.get("nan")); } try { moneyRepresentation.userToDatabase(sellPrice, 1); } catch (ParseException e) { editForm.recordError(sellPriceField, messages.get("nan")); } } protected Object onHistory() { try { Stock stock = (Stock) session.get(Stock.class, stockId); return ledgerLog.withFilter(eventLogger.grep(stock)); } catch (Exception e) { // should never get here } return null; } protected Object onSuccessFromEditForm() { if (eventDelete) { return doDelete(); } else { return doSave(); } } @CommitAfter private Object doSave() { Object ret = null; try { stock = (Stock) session.get(Stock.class, stockId); Stock backup = null; if (stock == null) { stock = new Stock(); } else { backup = new Stock(stock); } stock.setName(IdentUtil.findName(session, name)); stock.setVariant(IdentUtil.findVariant(session, variant)); stock.setAcquired(acquired); stock.setLiquidated(liquidated); stock.setSellPrice(moneyRepresentation.userToDatabase(sellPrice, 1)); stock.setBuyPrice(moneyRepresentation.userToDatabase(buyPrice, 1)); stock.setUnitCount(units); stock.setComment(comment); stock.setLocation(location); session.saveOrUpdate(stock); alertManager.alert(Duration.SINGLE, Severity.SUCCESS, messages.format("save-success", stock.getId())); focusedStockId = stock.getId(); if (backup == null) { eventLogger.acquired(stock); ret = this; } else { eventLogger.modified(backup); ret = Index.class; } } catch (Exception e) { alertManager.alert(Duration.SINGLE, Severity.ERROR, messages.format("exception", e.getMessage())); } return ret; } @CommitAfter private Object doDelete() { try { Stock bye = (Stock) session.get(Stock.class, stockId); long byeid = bye.getId(); bye.setName(null); bye.setVariant(null); session.delete(bye); focusedStockId = 0; Bookmark bm = (Bookmark) session.get(Bookmark.class, byeid); if (bm != null) { session.delete(bm); } alertManager.alert(Duration.SINGLE, Severity.SUCCESS, messages.format("delete-success", byeid)); eventLogger.deleted(bye); } catch (Exception e) { alertManager.alert(Duration.SINGLE, Severity.ERROR, messages.format("exception", e.getMessage())); // Only two ways of getting here: trying to delete something that no // longer exists or never existed in the first place. No need to tell the // user that throwing away something non-existant failed. } return Index.class; } public void afterRender() { javaScriptSupport .addScript("Mousetrap.prototype.stopCallback = function(e, element) {return false;};"); javaScriptSupport.addScript("Mousetrap.bind('esc', function() {window.history.back(); return false;});"); } }