package de.onyxbits.tradetrax.pages.edit; 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.Property; import org.apache.tapestry5.beaneditor.BeanModel; import org.apache.tapestry5.beaneditor.PropertyModel; import org.apache.tapestry5.corelib.components.Form; 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.BeanModelSource; import org.apache.tapestry5.services.javascript.JavaScriptSupport; import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.criterion.Criterion; import de.onyxbits.tradetrax.entities.Stock; import de.onyxbits.tradetrax.services.EventLogger; import de.onyxbits.tradetrax.services.SettingsStore; /** * An editor for splitting and merging {@link Stock}. * * @author patrick * */ @Import(library = "context:js/mousetrap.min.js") public class UnitsEditor { @Property private long stockId; @Property private Stock stock; @Property private Stock row; @Inject private BeanModelSource ledgerSource; @Component(id = "splitForm") private Form splitform; @Property private int size; @Component(id = "sizeField") private TextField sizeField; @Inject private Session session; @Inject private AlertManager alertManager; @Inject private Messages messages; @Inject private EventLogger eventLogger; @Inject private SettingsStore settingsStore; @Inject private JavaScriptSupport javaScriptSupport; @SuppressWarnings("unchecked") public List<Stock> getStocks() { Criteria crit = session.createCriteria(Stock.class); List<Criterion> lst = stock.allowedToMergeWith(); for (Criterion c : lst) { crit.add(c); } return crit.list(); } protected void onActivate(Long StockId) { this.stockId = StockId; stock = (Stock) session.get(Stock.class, stockId); size = 1; } public BeanModel<Stock> getLedgerModel() { BeanModel<Stock> model = ledgerSource.createDisplayModel(Stock.class, messages); List<String> lst = model.getPropertyNames(); for (String s : lst) { PropertyModel nameColumn = model.getById(s); nameColumn.sortable(false); } return model; } @CommitAfter protected Object onSuccess() { try { Stock offspring = stock.splitStock(size); session.save(offspring); session.update(stock); eventLogger.split(stock, offspring); } catch (Exception e) { alertManager.alert(Duration.SINGLE, Severity.ERROR, messages.format("exception", e.getMessage())); e.printStackTrace(); } return getClass(); } @CommitAfter protected void onMerge(long id) { try { Stock m = (Stock) session.load(Stock.class, id); Stock backup = (Stock) session.load(Stock.class, id); // Hibernate doesn't like an update and a delete in the same transaction // when this leads to the same row in a OneToMany mapping. Since we are // deleting "m" anyways, we can stop the cascade simply by setting the // references to null. m.setName(null); m.setVariant(null); stock.setUnitCount(stock.getUnitCount() + m.getUnitCount()); session.update(stock); session.delete(m); eventLogger.merged(stock, backup); } catch (Exception e) { e.printStackTrace(); alertManager.alert(Duration.SINGLE, Severity.ERROR, messages.format("exception", e.getMessage())); } } protected Long onPassivate() { return stockId; } public void afterRender() { javaScriptSupport .addScript("Mousetrap.prototype.stopCallback = function(e, element) {return false;};"); javaScriptSupport.addScript("Mousetrap.bind('esc', function() {window.history.back(); return false;});"); } }