/* ***************************************************************************** * JFire - it's hot - Free ERP System - http://jfire.org * * Copyright (C) 2004-2005 NightLabs - http://NightLabs.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public * * License as published by the Free Software Foundation; either * * version 2.1 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with this library; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin St, Fifth Floor, * * Boston, MA 02110-1301 USA * * * * Or get it online : * * http://opensource.org/licenses/lgpl-license.php * * * * * ******************************************************************************/ package org.nightlabs.jfire.trade.admin.ui.account; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.Set; import javax.jdo.FetchPlan; import javax.jdo.JDOHelper; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TableLayout; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.wizard.IWizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; 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.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.nightlabs.base.ui.composite.AbstractListComposite; import org.nightlabs.base.ui.composite.TimerText; import org.nightlabs.base.ui.composite.XComboComposite; import org.nightlabs.base.ui.composite.XComposite; import org.nightlabs.base.ui.exceptionhandler.ExceptionHandlerRegistry; import org.nightlabs.base.ui.job.Job; import org.nightlabs.base.ui.language.I18nTextEditor; import org.nightlabs.base.ui.resource.SharedImages; import org.nightlabs.base.ui.table.AbstractTableComposite; import org.nightlabs.base.ui.table.TableContentProvider; import org.nightlabs.base.ui.table.TableLabelProvider; import org.nightlabs.base.ui.wizard.DynamicPathWizardPage; import org.nightlabs.i18n.I18nTextBuffer; import org.nightlabs.jdo.NLJDOHelper; import org.nightlabs.jdo.query.QueryCollection; import org.nightlabs.jfire.accounting.Account; import org.nightlabs.jfire.accounting.AccountType; import org.nightlabs.jfire.accounting.AccountingManagerRemote; import org.nightlabs.jfire.accounting.Currency; import org.nightlabs.jfire.accounting.dao.AccountTypeDAO; import org.nightlabs.jfire.accounting.id.AccountTypeID; import org.nightlabs.jfire.accounting.query.AccountQuery; import org.nightlabs.jfire.base.JFireEjb3Factory; import org.nightlabs.jfire.base.login.ui.Login; import org.nightlabs.jfire.store.ProductType; import org.nightlabs.jfire.trade.admin.ui.TradeAdminPlugin; import org.nightlabs.jfire.trade.admin.ui.resource.Messages; import org.nightlabs.jfire.trade.ui.currency.CurrencyLabelProvider; import org.nightlabs.jfire.transfer.id.AnchorID; import org.nightlabs.progress.ProgressMonitor; import org.nightlabs.util.NLLocale; /** * @author Alexander Bieber <alex[AT]nightlabs[DOT]de> * @author Daniel Mazurek <daniel[AT]nightlabs[DOT]de> * */ public class CreateAccountEntryWizardPage extends DynamicPathWizardPage { class CheckIDJob extends Job { public CheckIDJob(String name) { super(name); } private String anchorID; // private String anchorTypeID; // private AccountTypeID accountTypeID; // public String getAnchorID() { // return anchorID; // } public void setAnchorID(String anchorID) { this.anchorID = anchorID; } // public void setAnchorTypeID(String anchorTypeID) { // this.anchorTypeID = anchorTypeID; // } // public void setAccountTypeID(AccountTypeID accountTypeID) { // this.accountTypeID = accountTypeID; // } @Override protected IStatus run(ProgressMonitor monitor) throws Exception { if (anchorID != null && !anchorID.isEmpty()) { AccountingManagerRemote acm = getAccountingManager(); // AnchorID id = AnchorID.create(Login.getLogin().getOrganisationID(), Account.ANCHOR_TYPE_ID_ACCOUNT, anchorID); // AccountSearchFilter filter = new AccountSearchFilter(); // filter.setOwner(id); // filter.setFieldEnabled("owner", true); // Set<AnchorID> anchorIDs = acm.getAccountIDs(filter); // AccountQuery query = new AccountQuery(); // query.setFieldEnabled(AccountQuery.FieldName.ownerID, true); // query.setOwnerID(id); // QueryCollection<AccountQuery> qc = new QueryCollection<AccountQuery>(Account.class, query); // Set<AnchorID> anchorIDs = acm.getAccountIDs(qc); AccountQuery query = new AccountQuery(); query.setFieldEnabled(AccountQuery.FieldName.anchorID, true); query.setAnchorID(anchorID); QueryCollection<AccountQuery> qc = new QueryCollection<AccountQuery>(Account.class, query); Set<AnchorID> anchorIDs = acm.getAccountIDs(qc); idAlreadyExisting = !anchorIDs.isEmpty(); if (idAlreadyExisting) { if (!getShell().isDisposed()) { getShell().getDisplay().asyncExec(new Runnable() { @Override public void run() { updatePage(); } }); } } } return Status.OK_STATUS; } }; private CheckIDJob checkIDJob = null; private boolean idAlreadyExisting = false; private XComposite wrapper = null; private I18nTextEditor accountNameEditor; // private Text anchorIDText; private TimerText anchorIDText; private XComboComposite<String> comboOwner; private XComboComposite<Currency> comboCurrency; private Group accountTypeGroup; private Button normalAccountRadio; private Button shadowAccountRadio; private List<Currency> currencies; private AbstractTableComposite<AccountType> accountTypeTable; public CreateAccountEntryWizardPage() { this(null); } /** * @param productTypeForAccount The productType this account is for (just for ID-suggestion) */ public CreateAccountEntryWizardPage(ProductType productTypeForAccount) { super( CreateAccountEntryWizardPage.class.getName(), Messages.getString("org.nightlabs.jfire.trade.admin.ui.account.CreateAccountEntryWizardPage.title"), //$NON-NLS-1$ SharedImages.getWizardPageImageDescriptor(TradeAdminPlugin.getDefault(), CreateAccountEntryWizardPage.class) ); } // private void updateIDText() { // if ( "".equals(accountNameEditor.getEditText()) ) //$NON-NLS-1$ // anchorIDText.setText(""); //$NON-NLS-1$ // else // anchorIDText.setText(ObjectIDUtil.makeValidIDString(accountNameEditor.getEditText())); // } protected AccountTypeID getSelectedAccounTypeID() { if (isCreateSummaryAccount()) { return AccountType.ACCOUNT_TYPE_ID_SUMMARY; } AccountType accountType = getAccountType(); if (accountType != null && accountType instanceof AccountType) return (AccountTypeID) JDOHelper.getObjectId(accountType); return null; } /** * @see org.nightlabs.base.ui.wizard.DynamicPathWizardPage#createPageContents(org.eclipse.swt.widgets.Composite) */ @Override public Control createPageContents(Composite parent) { wrapper = new XComposite(parent, SWT.NONE); GridLayout layout = new GridLayout(); layout.numColumns = 3; wrapper.setLayout(layout); getContainer().getShell().setText(Messages.getString("org.nightlabs.jfire.trade.admin.ui.account.CreateAccountEntryWizardPage.windowTitle")); //$NON-NLS-1$ checkIDJob = new CheckIDJob("Check account id"); Composite idWrapper = new XComposite(wrapper, SWT.NONE); idWrapper.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); Label idLabel = new Label(idWrapper, SWT.NONE); idLabel.setText("ID"); anchorIDText = new TimerText(idWrapper, wrapper.getBorderStyle()); anchorIDText.setText(""); //$NON-NLS-1$ GridData anchorIDTextLData = new GridData(GridData.FILL_HORIZONTAL); anchorIDText.setLayoutData(anchorIDTextLData); anchorIDText.addDelayedModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent evt) { if (!getShell().isDisposed()) { getShell().getDisplay().asyncExec(new Runnable() { @Override public void run() { updatePage(); checkIDJob.setAnchorID(anchorIDText.getText()); checkIDJob.setSystem(true); checkIDJob.schedule(); } }); } } }); accountNameEditor = new I18nTextEditor(wrapper, "Language"); GridData accountNameEditorGD = new GridData(GridData.FILL_HORIZONTAL); accountNameEditorGD.horizontalSpan = 1; accountNameEditor.setLayoutData(accountNameEditorGD); accountNameEditor.setI18nText(new I18nTextBuffer()); accountNameEditor.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { updatePage(); // updateIDText(); } }); // comboOwner = new XComboComposite<String>(wrapper, AbstractListComposite.getDefaultWidgetStyle(wrapper), // Messages.getString("org.nightlabs.jfire.trade.admin.ui.account.CreateAccountEntryWizardPage.ownerCombo.caption")); //$NON-NLS-1$ // // comboOwner.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); // comboOwner.setEnabled(false); comboCurrency = new XComboComposite<Currency>(wrapper, AbstractListComposite.getDefaultWidgetStyle(wrapper), Messages.getString("org.nightlabs.jfire.trade.admin.ui.account.CreateAccountEntryWizardPage.currencyCombo.caption"), new CurrencyLabelProvider()); //$NON-NLS-1$ comboCurrency.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); try { Collection<Currency> tmpCurrenies = getAccountingManager().getCurrencies(new String[]{FetchPlan.DEFAULT}, NLJDOHelper.MAX_FETCH_DEPTH_NO_LIMIT); currencies = new ArrayList<Currency>(tmpCurrenies.size()); currencies.addAll(tmpCurrenies); } catch (Exception e) { ExceptionHandlerRegistry.asyncHandleException(e); } comboCurrency.setInput(currencies); if (! currencies.isEmpty()) comboCurrency.selectElementByIndex(0); // getCombo().add(currency.getCurrencyID()+" ("+currency.getCurrencySymbol()+")"); //$NON-NLS-1$ //$NON-NLS-2$ accountTypeGroup = new Group(wrapper, SWT.NONE); GridData gd = new GridData(GridData.FILL_BOTH); gd.horizontalSpan = 3; // gd.verticalAlignment = GridData.CENTER; accountTypeGroup.setLayoutData(gd); GridLayout gl = new GridLayout(); gl.numColumns = 1; accountTypeGroup.setLayout(gl); normalAccountRadio = new Button(accountTypeGroup, SWT.RADIO | SWT.WRAP); normalAccountRadio.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); normalAccountRadio.setText(Messages.getString("org.nightlabs.jfire.trade.admin.ui.account.CreateAccountEntryWizardPage.radioNormalAccount.text")); //$NON-NLS-1$ normalAccountRadio.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { updatePage(); } public void widgetDefaultSelected(SelectionEvent e) { } }); normalAccountRadio.setSelection(true); accountTypeTable = new AbstractTableComposite<AccountType>(accountTypeGroup, SWT.NONE) { @Override protected void createTableColumns(TableViewer tableViewer, Table table) { table.setHeaderVisible(false); TableColumn col = new TableColumn(table, SWT.LEFT); TableLayout l = new TableLayout(); l.addColumnData(new ColumnWeightData(1)); table.setLayout(l); } @Override protected void setTableProvider(TableViewer tableViewer) { tableViewer.setLabelProvider(new TableLabelProvider() { public String getColumnText(Object element, int columnIndex) { return ((AccountType)element).getName().getText(); } }); tableViewer.setContentProvider(new TableContentProvider()); } }; accountTypeTable.getGridData().minimumHeight = 80; // accountTypeTable.setInput(new String[] {AccountType.ACCOUNT_TYPE_ID_LOCAL_REVENUE, AccountType.ANCHOR_TYPE_ID_LOCAL_EXPENSE}); AccountType dummy = new AccountType("dummy.a.b", "dummy", false); //$NON-NLS-1$ //$NON-NLS-2$ dummy.getName().setText(NLLocale.getDefault().getLanguage(), Messages.getString("org.nightlabs.jfire.trade.admin.ui.account.CreateAccountEntryWizardPage.name.loading")); //$NON-NLS-1$ accountTypeTable.setInput(Collections.singletonList(dummy)); Job job = new Job(Messages.getString("org.nightlabs.jfire.trade.admin.ui.account.CreateAccountEntryWizardPage.jon.loadAccountTypes.name")) { //$NON-NLS-1$ @Override protected IStatus run(ProgressMonitor monitor) throws Exception { final List<AccountType> accountTypes = AccountTypeDAO.sharedInstance().getAccountTypes( new String[] { FetchPlan.DEFAULT, AccountType.FETCH_GROUP_NAME }, NLJDOHelper.MAX_FETCH_DEPTH_NO_LIMIT, monitor ); // the account-type "Summary" is specially handled because we need to instantiate a subclass - maybe we'll simplify the UI one day to solely show // the list and *not* additionally the radio buttons for (Iterator<AccountType> it = accountTypes.iterator(); it.hasNext();) { AccountType accountType = it.next(); if (AccountType.ACCOUNT_TYPE_ID_SUMMARY.equals(JDOHelper.getObjectId(accountType))) it.remove(); } Collections.sort(accountTypes, new Comparator<AccountType>() { @Override public int compare(AccountType o1, AccountType o2) { return o1.getName().getText().compareTo(o2.getName().getText()); } }); Display.getDefault().asyncExec(new Runnable() { @Override public void run() { accountTypeTable.setInput(accountTypes); } }); return Status.OK_STATUS; } }; job.schedule(); accountTypeTable.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { updatePage(); } }); shadowAccountRadio = new Button(accountTypeGroup, SWT.RADIO); shadowAccountRadio.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); shadowAccountRadio.setText(Messages.getString("org.nightlabs.jfire.trade.admin.ui.account.CreateAccountEntryWizardPage.radioSummaryAccount.text")); //$NON-NLS-1$ shadowAccountRadio.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { updatePage(); } public void widgetDefaultSelected(SelectionEvent e) { } }); // updatePage(); setPageComplete(false); return wrapper; } /** * Checks page status */ protected void updatePage() { accountTypeTable.setEnabled(normalAccountRadio.getSelection()); if ( "".equals(anchorIDText.getText()) ) { //$NON-NLS-1$ updateStatus(Messages.getString("org.nightlabs.jfire.trade.admin.ui.account.CreateAccountEntryWizardPage.errorMessageNoAnchorID")); //$NON-NLS-1$ return; } if ( "".equals(accountNameEditor.getEditText()) ) { //$NON-NLS-1$ updateStatus("No Name entered"); return; } if (comboCurrency.getSelectionIndex() < 0) { updateStatus(Messages.getString("org.nightlabs.jfire.trade.admin.ui.account.CreateAccountEntryWizardPage.errorMessageNoCurrency")); //$NON-NLS-1$ return; } if (normalAccountRadio.getSelection() && accountTypeTable.getFirstSelectedElement() == null) { updateStatus(Messages.getString("org.nightlabs.jfire.trade.admin.ui.account.CreateAccountEntryWizardPage.message.selectAccountType")); //$NON-NLS-1$ return; } if (idAlreadyExisting) { updateStatus("There exists already an Account with the ID "+getAnchorID()); return; } updateStatus(null); } /** * Returns true. Can be last page, when user just creates * an account, and does not perform any configuration. * */ @Override public boolean canBeLastPage() { return true; } /** * @see org.nightlabs.base.ui.wizard.DynamicPathWizardPage#getDefaultPageMessage() */ @Override protected String getDefaultPageMessage() { return Messages.getString("org.nightlabs.jfire.trade.admin.ui.account.CreateAccountEntryWizardPage.defaultPageMessage"); //$NON-NLS-1$ } @Override public IWizardPage getNextPage() { if (!isPageComplete()) return null; else { return null; } } public boolean isCreateSummaryAccount() { return shadowAccountRadio.getSelection(); } public String getAnchorID() { return anchorIDText.getText(); } public Currency getCurrency() { if (comboCurrency.getSelectionIndex() < 0) throw new IllegalStateException("No currency selected. Can't return one."); //$NON-NLS-1$ return currencies.get(comboCurrency.getSelectionIndex()); } public I18nTextEditor getAccountNameEditor() { return accountNameEditor; } // public String getAnchorTypeID() { // return accountTypeTable.getFirstSelectedElement(); // } public AccountType getAccountType() { return accountTypeTable.getFirstSelectedElement(); } /** * @return A new {@link AccountingManager}. */ private AccountingManagerRemote getAccountingManager() { try { return JFireEjb3Factory.getRemoteBean(AccountingManagerRemote.class, Login.getLogin().getInitialContextProperties()); } catch (Exception e) { throw new RuntimeException(e); } } }