package org.nightlabs.jfire.trade.quicksale.ui; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.jdo.FetchPlan; import javax.jdo.JDOHelper; import javax.security.auth.login.LoginException; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.forms.editor.FormEditor; import org.eclipse.ui.forms.editor.IFormPage; import org.nightlabs.base.ui.composite.XComposite; import org.nightlabs.base.ui.composite.XComposite.LayoutDataMode; import org.nightlabs.base.ui.composite.XComposite.LayoutMode; import org.nightlabs.base.ui.entity.editor.EntityEditor; import org.nightlabs.base.ui.entity.editor.EntityEditorPageController; import org.nightlabs.base.ui.entity.editor.IEntityEditorPageController; import org.nightlabs.base.ui.entity.editor.IEntityEditorPageFactory; import org.nightlabs.base.ui.resource.SharedImages; import org.nightlabs.base.ui.util.RCPUtil; import org.nightlabs.base.ui.wizard.DynamicPathWizardDialog; import org.nightlabs.jdo.NLJDOHelper; import org.nightlabs.jfire.base.JFireEjb3Factory; import org.nightlabs.jfire.base.login.ui.Login; import org.nightlabs.jfire.base.ui.config.ConfigUtil; import org.nightlabs.jfire.trade.Article; import org.nightlabs.jfire.trade.LegalEntity; import org.nightlabs.jfire.trade.TradeManagerRemote; import org.nightlabs.jfire.trade.config.TradeConfigModule; import org.nightlabs.jfire.trade.dao.ArticleDAO; import org.nightlabs.jfire.trade.dao.LegalEntityDAO; import org.nightlabs.jfire.trade.id.ArticleContainerID; import org.nightlabs.jfire.trade.id.ArticleID; import org.nightlabs.jfire.trade.id.OrderID; import org.nightlabs.jfire.trade.id.SegmentTypeID; import org.nightlabs.jfire.trade.quicksale.ui.resource.Messages; import org.nightlabs.jfire.trade.ui.TradePlugin; import org.nightlabs.jfire.trade.ui.articlecontainer.detail.ActiveSegmentEditSelectionEvent; import org.nightlabs.jfire.trade.ui.articlecontainer.detail.ActiveSegmentEditSelectionListener; import org.nightlabs.jfire.trade.ui.articlecontainer.detail.ArticleChangeEvent; import org.nightlabs.jfire.trade.ui.articlecontainer.detail.ArticleChangeListener; import org.nightlabs.jfire.trade.ui.articlecontainer.detail.ArticleContainerEditorInput; import org.nightlabs.jfire.trade.ui.articlecontainer.detail.ArticleContainerEditorPage; import org.nightlabs.jfire.trade.ui.articlecontainer.detail.ArticleCreateEvent; import org.nightlabs.jfire.trade.ui.articlecontainer.detail.ArticleCreateListener; import org.nightlabs.jfire.trade.ui.articlecontainer.detail.ArticleSelection; import org.nightlabs.jfire.trade.ui.articlecontainer.detail.ArticleStatusCheckResult; import org.nightlabs.jfire.trade.ui.articlecontainer.detail.ClientArticleSegmentGroupSet; import org.nightlabs.jfire.trade.ui.articlecontainer.detail.SegmentEdit; import org.nightlabs.jfire.trade.ui.articlecontainer.detail.SegmentEditArticleSelectionEvent; import org.nightlabs.jfire.trade.ui.articlecontainer.detail.SegmentEditArticleSelectionListener; import org.nightlabs.jfire.trade.ui.legalentity.view.LegalEntityEditorView; import org.nightlabs.jfire.trade.ui.legalentity.view.SelectAnonymousViewAction; import org.nightlabs.jfire.trade.ui.reserve.ReservationPaymentDeliveryWizard; import org.nightlabs.jfire.trade.ui.reserve.ReservationWizardDialog; import org.nightlabs.jfire.trade.ui.transfer.wizard.AbstractCombiTransferWizard; import org.nightlabs.jfire.trade.ui.transfer.wizard.CombiTransferArticleContainerWizard; import org.nightlabs.jfire.trade.ui.transfer.wizard.QuickSaleErrorHandler; import org.nightlabs.jfire.trade.ui.transfer.wizard.TransferWizard; import org.nightlabs.jfire.transfer.id.AnchorID; import org.nightlabs.progress.NullProgressMonitor; import org.nightlabs.progress.ProgressMonitor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Daniel.Mazurek [at] NightLabs [dot] de * @author Alexander Bieber <!-- alex [AT] nightlabs [DOT] de --> */ public class ArticleContainerQuickSaleEditorPage extends ArticleContainerEditorPage { private static final Logger logger = LoggerFactory.getLogger(ArticleContainerQuickSaleEditorPage.class); public static class Factory implements IEntityEditorPageFactory { @Override public IFormPage createPage(FormEditor formEditor) { return new ArticleContainerQuickSaleEditorPage(formEditor); } @Override public IEntityEditorPageController createPageController(EntityEditor editor) { return new EntityEditorPageController(editor) { @Override public void doLoad(ProgressMonitor monitor) { } @Override public boolean doSave(ProgressMonitor monitor) { return true; } }; } } private XComposite wrapper; private Composite buttonComp; private Button okButtonCustomer; private Button okButtonAnonymous; private Button deleteSelectionButton; private Text customerSearchText; private Button deleteAllButton; // private Button reverseButton; /** */ public ArticleContainerQuickSaleEditorPage(FormEditor editor) { super(editor); } @Override protected Composite createComposite(Composite parent) { wrapper = new XComposite(parent, SWT.NONE, LayoutMode.TIGHT_WRAPPER); createComposite(wrapper, ((ArticleContainerEditorInput)getEditorInput()).getArticleContainerID()); return wrapper; } protected void createComposite(Composite parent, ArticleContainerID articleContainerID) { // getArticleContainerEdit().setShowHeader(false); getArticleContainerEdit().createComposite(parent); getArticleContainerEdit().setShowHeader(false); XComposite wrapper = new XComposite(parent, SWT.NONE, LayoutDataMode.GRID_DATA_HORIZONTAL); buttonComp = new XComposite(wrapper, SWT.NONE); buttonComp.setLayout(new GridLayout(8, false)); buttonComp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); deleteAllButton = new Button(buttonComp, SWT.FLAT); deleteAllButton.setText(Messages.getString("org.nightlabs.jfire.trade.quicksale.ui.ArticleContainerQuickSaleEditorPage.deleteAllButton.text")); //$NON-NLS-1$ deleteAllButton.setImage(SharedImages.DELETE_16x16.createImage()); deleteAllButton.addSelectionListener(deleteAllListener); deleteSelectionButton = new Button(buttonComp, SWT.FLAT); deleteSelectionButton.setText(Messages.getString("org.nightlabs.jfire.trade.quicksale.ui.ArticleContainerQuickSaleEditorPage.button.deleteSelection.text")); //$NON-NLS-1$ deleteSelectionButton.setImage(SharedImages.DELETE_16x16.createImage()); deleteSelectionButton.addSelectionListener(deleteSelectionListener); deleteSelectionButton.setEnabled(false); // need to add listeners for activeSegmentEdit by this listener, because at this time activeSegementEdit is null getArticleContainerEdit().addActiveSegmentEditSelectionListener(new ActiveSegmentEditSelectionListener(){ @Override public void selected(ActiveSegmentEditSelectionEvent event) { // add listener to check for articleSelection to set enable state for deleteSelectionButton event.getActiveSegmentEdit().addSegmentEditArticleSelectionListener(segmentEditArticleSelectionListener); } }); Label spacerLabel = new Label(buttonComp, SWT.NONE); spacerLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); Label customerSearchLabel = new Label(buttonComp, SWT.NONE); customerSearchLabel.setText(Messages.getString("org.nightlabs.jfire.trade.quicksale.ui.ArticleContainerQuickSaleEditorPage.customerSearchLabel.text")); //$NON-NLS-1$ customerSearchText = new Text(buttonComp, wrapper.getBorderStyle()); GridData textData = new GridData(); textData.widthHint = 100; textData.heightHint = 15; textData.minimumWidth = 100; customerSearchText.setLayoutData(textData); customerSearchText.addSelectionListener(okListenerCustomer); okButtonCustomer = new Button(buttonComp, SWT.FLAT); okButtonCustomer.setText(Messages.getString("org.nightlabs.jfire.trade.quicksale.ui.ArticleContainerQuickSaleEditorPage.okButtonCustomer.text")); //$NON-NLS-1$ okButtonCustomer.setImage(SharedImages.getSharedImage(TradePlugin.getDefault(), LegalEntityEditorView.class)); okButtonCustomer.addSelectionListener(okListenerCustomer); // Label separator = new Label(buttonComp, SWT.SEPARATOR); okButtonAnonymous = new Button(buttonComp, SWT.FLAT); okButtonAnonymous.setText(Messages.getString("org.nightlabs.jfire.trade.quicksale.ui.ArticleContainerQuickSaleEditorPage.okButtonAnonymous.text")); //$NON-NLS-1$ okButtonAnonymous.setImage(SharedImages.getSharedImage(TradePlugin.getDefault(), SelectAnonymousViewAction.class)); okButtonAnonymous.addSelectionListener(okListenerAnonymous); getArticleContainerEdit().addArticleChangeListener(articleChangeListener); getArticleContainerEdit().addArticleCreateListener(articleCreateListener); buttonComp.setEnabled(false); } /** * Returns a Set of all {@link ArticleID} of those {@link Article}s which do not have the allocated or reversed status * form the given Set of {@link ArticleSelection}s. * * @param selections a Set of {@link ArticleSelection} which should be checked * @return a Set of all {@link ArticleID} of those {@link Article}s which do not have the allocated or reversed status */ protected ArticleStatusCheckResult getArticleStatusCheckResult(Set<ArticleSelection> selections) { return new ArticleStatusCheckResult(ArticleSelection.getSelectedArticles(selections)); } private SegmentEditArticleSelectionListener segmentEditArticleSelectionListener = new SegmentEditArticleSelectionListener() { public void selected(SegmentEditArticleSelectionEvent event) { if (!event.getArticleSelections().isEmpty()) { // we check if all articles are non-allocated, allocated or reversed, only then they can be removed ArticleStatusCheckResult articleStatusCheckResult = getArticleStatusCheckResult(event.getArticleSelections()); deleteSelectionButton.setEnabled(articleStatusCheckResult.isAllArticlesAllocatedOrReversed()); } else { deleteSelectionButton.setEnabled(false); } } }; private SelectionListener okListenerCustomer = new SelectionListener(){ public void widgetSelected(SelectionEvent e) { String text = customerSearchText.getText(); OrderID orderID = (OrderID) getArticleContainerEdit().getArticleContainerID(); // CustomerPaymentDeliveryWizard wiz = new CustomerPaymentDeliveryWizard( ReservationPaymentDeliveryWizard wiz = new ReservationPaymentDeliveryWizard( text, orderID, AbstractCombiTransferWizard.TRANSFER_MODE_BOTH, TransferWizard.Side.Vendor); // DynamicPathWizardDialog dlg = new DynamicPathWizardDialog(wiz); DynamicPathWizardDialog dlg = new ReservationWizardDialog(wiz); int returnCode = dlg.open(); boolean transferSuccessful = wiz.isTransfersSuccessful(); if (logger.isDebugEnabled()) { logger.debug("ReservationWizardDialog OrderID = "+orderID); //$NON-NLS-1$ logger.debug("ReservationWizardDialog returnCode = "+returnCode); //$NON-NLS-1$ logger.debug("ReservationWizardDialog.isTransfersSuccessful() = "+transferSuccessful); //$NON-NLS-1$ } if (returnCode == Dialog.OK && transferSuccessful) { createNewOrder(); } } public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } }; private SelectionListener okListenerAnonymous = new SelectionListener(){ public void widgetSelected(SelectionEvent e) { LegalEntity legalEntity = LegalEntityDAO.sharedInstance().getAnonymousLegalEntity( new NullProgressMonitor() ); assignToCustomer(legalEntity); if (payAndDeliverAll()) { createNewOrder(); } } public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } }; private SelectionListener deleteAllListener = new SelectionAdapter(){ @Override public void widgetSelected(SelectionEvent e) { deleteAll(); } }; private SelectionListener deleteSelectionListener = new SelectionAdapter(){ @Override public void widgetSelected(SelectionEvent e) { deleteSelection(); } }; public static ArticleContainerEditorInput createEditorInput() { TradeManagerRemote tm; try { try { Login.getLogin(); TradeConfigModule tradeConfigModule = ConfigUtil.getUserCfMod( TradeConfigModule.class, new String[] { FetchPlan.DEFAULT, TradeConfigModule.FETCH_GROUP_CURRENCY, }, NLJDOHelper.MAX_FETCH_DEPTH_NO_LIMIT, new NullProgressMonitor()); // TODO async! tm = JFireEjb3Factory.getRemoteBean(TradeManagerRemote.class, Login.getLogin().getInitialContextProperties()); // by default get the customerID of the anonymous customer AnchorID customerID = (AnchorID) JDOHelper.getObjectId( LegalEntityDAO.sharedInstance().getAnonymousLegalEntity( new NullProgressMonitor() ) ); // FIXME IDPREFIX (next line) should be asked from user if necessary! OrderID orderID = tm.createQuickSaleWorkOrder( customerID, null, tradeConfigModule.getCurrencyID(), new SegmentTypeID[] {null}); // null here is a shortcut for default segment type return new ArticleContainerEditorInput(orderID); } catch (LoginException le) { return null; } } catch (Throwable t) { throw new RuntimeException(t); } } // private ArticleCreateListener articleCreateListener = new ArticleCreateListener(){ // public void articlesCreated(ArticleCreateEvent articleCreateEvent) { // if (buttonComp != null && !buttonComp.isDisposed()) // buttonComp.setEnabled(true); // } // }; private Set<Article> articlesWithWrongState = new HashSet<Article>(); private void checkAllArticlesAreAllocatedOrReversed(Collection<? extends Article> deletedArticles) { ArticleStatusCheckResult articleStatusCheckResult = new ArticleStatusCheckResult(getArticleContainerEdit().getArticles()); articlesWithWrongState.addAll(articleStatusCheckResult.getNotAllocatedNorReversedArticles()); articlesWithWrongState.removeAll(articleStatusCheckResult.getAllocatedOrReversedArticles()); if (deletedArticles != null) articlesWithWrongState.removeAll(deletedArticles); if (buttonComp != null && !buttonComp.isDisposed()) buttonComp.setEnabled(articlesWithWrongState.isEmpty()); } private ArticleCreateListener articleCreateListener = new ArticleCreateListener(){ public void articlesCreated(ArticleCreateEvent articleCreateEvent) { checkAllArticlesAreAllocatedOrReversed(null); } }; private ArticleChangeListener articleChangeListener = new ArticleChangeListener(){ public void articlesChanged(ArticleChangeEvent articleChangeEvent) { checkAllArticlesAreAllocatedOrReversed(articleChangeEvent.getDeletedArticles()); } }; protected void assignToCustomer(LegalEntity legalEntity) { TradeManagerRemote tm = TradePlugin.getDefault().getTradeManager(); AnchorID customerID = (AnchorID) JDOHelper.getObjectId(legalEntity); OrderID orderID = (OrderID) getArticleContainerEdit().getArticleContainerID(); try { tm.assignCustomer(orderID, customerID, true, null, 1); } catch (Exception e) { throw new RuntimeException(e); } } protected boolean payAndDeliverAll() { CombiTransferArticleContainerWizard wizard = new CombiTransferArticleContainerWizard( getArticleContainerEdit().getArticleContainerID(), AbstractCombiTransferWizard.TRANSFER_MODE_BOTH); wizard.setErrorHandler(new QuickSaleErrorHandler()); DynamicPathWizardDialog dialog = new DynamicPathWizardDialog(wizard); int returnCode = dialog.open(); if (returnCode == Window.CANCEL) return false; return wizard.isTransfersSuccessful(); } protected void deleteAll() { try { // TradeManager tradeManager = TradePlugin.getDefault().getTradeManager(); // Collection<Article> articles = tradeManager.releaseArticles(NLJDOHelper.getObjectIDSet( // getArticleContainerEdit().getArticles()), true, false, null, // NLJDOHelper.MAX_FETCH_DEPTH_NO_LIMIT); // Set<ObjectID> articleIDs = NLJDOHelper.getObjectIDSet(getArticleContainerEdit().getArticles()); // tradeManager.deleteArticles(articleIDs, true); // I think this is not necessary, because the articles are deleted automatically via the EditLock-release-hook createNewOrder(); } catch (Exception e) { throw new RuntimeException(e); } } protected void deleteSelection() { // We remove the lines from the server - therefore find out first, what lines shall be handled here. SegmentEdit segmentEdit = getArticleContainerEdit().getActiveSegmentEdit(); Set<? extends ArticleSelection> articleSelections = segmentEdit.getArticleSelections(); if (!articleSelections.isEmpty()) { Set<ArticleID> articleIDs = new HashSet<ArticleID>(); for (ArticleSelection articleSelection : articleSelections) { for (Article article : articleSelection.getSelectedArticles()) { articleIDs.add((ArticleID) JDOHelper.getObjectId(article)); } } final Composite composite = getArticleContainerEdit().getActiveSegmentEdit().getComposite(); // Composite composite = articleContainerEdit; try { if (!composite.isDisposed()) { composite.setEnabled(false); buttonComp.setEnabled(false); } ArticleChangeListener articleChangeListener = new ArticleChangeListener(){ @Override public void articlesChanged(ArticleChangeEvent articleChangeEvent) { if (!composite.isDisposed()) { composite.setEnabled(true); buttonComp.setEnabled(true); } getArticleContainerEdit().removeArticleChangeListener(this); } }; getArticleContainerEdit().addArticleChangeListener(articleChangeListener); // TradeManager tradeManager = TradePlugin.getDefault().getTradeManager(); // Collection<Article> articles = tradeManager.releaseArticles(articleIDs, // true, false, null, NLJDOHelper.MAX_FETCH_DEPTH_NO_LIMIT); // tradeManager.deleteArticles(articleIDs, true); ClientArticleSegmentGroupSet clientArticleSegmentGroupSet = getArticleContainerEdit().getArticleSegmentGroupSet(); List<Article> articles = ArticleDAO.sharedInstance().deleteArticles( articleIDs, true, true, clientArticleSegmentGroupSet.getFetchGroupsArticle(), clientArticleSegmentGroupSet.getMaxFetchDepthArticle(), new NullProgressMonitor() ); Set<ArticleID> deletedArticleIDs = new HashSet<ArticleID>(articleIDs); for (Article article : articles) { deletedArticleIDs.remove(JDOHelper.getObjectId(article)); } clientArticleSegmentGroupSet.updateArticles(deletedArticleIDs, articles); } catch (Exception e) { if (!composite.isDisposed()) { composite.setEnabled(true); buttonComp.setEnabled(true); } throw new RuntimeException(e); } } } protected void createNewOrder() { // only close, open will occur automatically because of partListener in ArticleContainerQuickSaleEditor RCPUtil.closeEditor(getEditorInput(), false); } }