Source Code Cross Referenced for UnreconciledSection.java in  » ERP-CRM-Financial » jmoney » net » sf » jmoney » reconciliation » reconcilePage » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » ERP CRM Financial » jmoney » net.sf.jmoney.reconciliation.reconcilePage 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *
003:         *  JMoney - A Personal Finance Manager
004:         *  Copyright (c) 2004 Nigel Westbury <westbury@users.sourceforge.net>
005:         *
006:         *
007:         *  This program is free software; you can redistribute it and/or modify
008:         *  it under the terms of the GNU General Public License as published by
009:         *  the Free Software Foundation; either version 2 of the License, or
010:         *  (at your option) any later version.
011:         *
012:         *  This program is distributed in the hope that it will be useful,
013:         *  but WITHOUT ANY WARRANTY; without even the implied warranty of
014:         *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
015:         *  GNU General Public License for more details.
016:         *
017:         *  You should have received a copy of the GNU General Public License
018:         *  along with this program; if not, write to the Free Software
019:         *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
020:         *
021:         */
022:
023:        package net.sf.jmoney.reconciliation.reconcilePage;
024:
025:        import java.net.URL;
026:        import java.util.ArrayList;
027:        import java.util.Collection;
028:        import java.util.Vector;
029:
030:        import net.sf.jmoney.JMoneyPlugin;
031:        import net.sf.jmoney.entrytable.BalanceColumn;
032:        import net.sf.jmoney.entrytable.BaseEntryRowControl;
033:        import net.sf.jmoney.entrytable.Block;
034:        import net.sf.jmoney.entrytable.ButtonCellControl;
035:        import net.sf.jmoney.entrytable.CellBlock;
036:        import net.sf.jmoney.entrytable.DebitAndCreditColumns;
037:        import net.sf.jmoney.entrytable.EntriesTable;
038:        import net.sf.jmoney.entrytable.EntryData;
039:        import net.sf.jmoney.entrytable.EntryRowControl;
040:        import net.sf.jmoney.entrytable.HorizontalBlock;
041:        import net.sf.jmoney.entrytable.ICellControl;
042:        import net.sf.jmoney.entrytable.IEntriesContent;
043:        import net.sf.jmoney.entrytable.IRowProvider;
044:        import net.sf.jmoney.entrytable.IndividualBlock;
045:        import net.sf.jmoney.entrytable.OtherEntriesButton;
046:        import net.sf.jmoney.entrytable.PropertyBlock;
047:        import net.sf.jmoney.entrytable.ReusableRowProvider;
048:        import net.sf.jmoney.entrytable.RowSelectionTracker;
049:        import net.sf.jmoney.entrytable.SingleOtherEntryPropertyBlock;
050:        import net.sf.jmoney.entrytable.SplitEntryRowControl;
051:        import net.sf.jmoney.isolation.TransactionManager;
052:        import net.sf.jmoney.isolation.UncommittedObjectKey;
053:        import net.sf.jmoney.model2.Currency;
054:        import net.sf.jmoney.model2.Entry;
055:        import net.sf.jmoney.model2.EntryInfo;
056:        import net.sf.jmoney.model2.Transaction;
057:        import net.sf.jmoney.model2.TransactionInfo;
058:        import net.sf.jmoney.reconciliation.BankStatement;
059:        import net.sf.jmoney.reconciliation.ReconciliationEntryInfo;
060:        import net.sf.jmoney.reconciliation.ReconciliationPlugin;
061:
062:        import org.eclipse.jface.dialogs.MessageDialog;
063:        import org.eclipse.jface.resource.ImageDescriptor;
064:        import org.eclipse.jface.util.LocalSelectionTransfer;
065:        import org.eclipse.jface.viewers.StructuredSelection;
066:        import org.eclipse.swt.SWT;
067:        import org.eclipse.swt.dnd.DND;
068:        import org.eclipse.swt.dnd.DragSource;
069:        import org.eclipse.swt.dnd.DragSourceEvent;
070:        import org.eclipse.swt.dnd.DragSourceListener;
071:        import org.eclipse.swt.dnd.Transfer;
072:        import org.eclipse.swt.events.DisposeEvent;
073:        import org.eclipse.swt.events.DisposeListener;
074:        import org.eclipse.swt.graphics.Image;
075:        import org.eclipse.swt.widgets.Composite;
076:        import org.eclipse.swt.widgets.Label;
077:        import org.eclipse.ui.forms.SectionPart;
078:        import org.eclipse.ui.forms.widgets.FormToolkit;
079:        import org.eclipse.ui.forms.widgets.Section;
080:
081:        /**
082:         * Class implementing the section containing the unreconciled
083:         * entries on the account reconciliation page.
084:         * 
085:         * @author Nigel Westbury
086:         */
087:        public class UnreconciledSection extends SectionPart {
088:
089:            ReconcilePage fPage;
090:
091:            EntriesTable fUnreconciledEntriesControl;
092:
093:            FormToolkit toolkit;
094:
095:            IEntriesContent unreconciledTableContents = null;
096:
097:            ArrayList<CellBlock<EntryData, EntryRowControl>> cellList;
098:
099:            public UnreconciledSection(ReconcilePage page, Composite parent,
100:                    RowSelectionTracker rowTracker) {
101:                super (parent, page.getManagedForm().getToolkit(),
102:                        Section.TITLE_BAR);
103:                getSection().setText("Unreconciled Entries");
104:                fPage = page;
105:                this .toolkit = page.getManagedForm().getToolkit();
106:
107:                unreconciledTableContents = new IEntriesContent() {
108:                    public Collection<Entry> getEntries() {
109:                        /* The caller always sorts, so there is no point in us returning
110:                         * sorted results.  It may be at some point we decide it is more
111:                         * efficient to get the database to sort for us, but that would
112:                         * only help the first time the results are fetched, it would not
113:                         * help on a re-sort.  It also only helps if the database indexes
114:                         * on the date.		
115:                        CurrencyAccount account = fPage.getAccount();
116:                        Collection<Entry> accountEntries = 
117:                        	account
118:                        		.getSortedEntries(TransactionInfo.getDateAccessor(), false);
119:                         */
120:                        Collection<Entry> accountEntries = fPage.getAccount()
121:                                .getEntries();
122:
123:                        Vector<Entry> requiredEntries = new Vector<Entry>();
124:                        for (Entry entry : accountEntries) {
125:                            if (entry.getPropertyValue(ReconciliationEntryInfo
126:                                    .getStatementAccessor()) == null) {
127:                                requiredEntries.add(entry);
128:                            }
129:                        }
130:
131:                        return requiredEntries;
132:                    }
133:
134:                    public boolean isEntryInTable(Entry entry) {
135:                        // This entry is to be shown if the account
136:                        // matches and no statement is set.
137:                        BankStatement statement = entry
138:                                .getPropertyValue(ReconciliationEntryInfo
139:                                        .getStatementAccessor());
140:                        return fPage.getAccount().equals(entry.getAccount())
141:                                && statement == null;
142:                    }
143:
144:                    public boolean filterEntry(EntryData data) {
145:                        // No filter here, so entries always match
146:                        return true;
147:                    }
148:
149:                    public long getStartBalance() {
150:                        // TODO: figure out how we keep this up to date.
151:                        // The EntriesTree class has no mechanism for refreshing
152:                        // the opening balance.  It should have.
153:                        return 0;
154:                    }
155:
156:                    public Entry createNewEntry(Transaction newTransaction) {
157:                        Entry entryInTransaction = newTransaction.createEntry();
158:                        Entry otherEntry = newTransaction.createEntry();
159:
160:                        setNewEntryProperties(entryInTransaction);
161:
162:                        // TODO: See if this code has any effect, and
163:                        // should this be here at all?
164:                        /*
165:                         * We set the currency by default to be the currency of the
166:                         * top-level entry.
167:                         * 
168:                         * The currency of an entry is not applicable if the entry is an
169:                         * entry in a currency account or an income and expense account
170:                         * that is restricted to a single currency.
171:                         * However, we set it anyway so the value is there if the entry
172:                         * is set to an account which allows entries in multiple currencies.
173:                         * 
174:                         * It may be that the currency of the top-level entry is not
175:                         * known. This is not possible if entries in a currency account
176:                         * are being listed, but may be possible if this entries list
177:                         * control is used for more general purposes. In this case, the
178:                         * currency is not set and so the user must enter it.
179:                         */
180:                        if (entryInTransaction.getCommodity() instanceof  Currency) {
181:                            otherEntry
182:                                    .setIncomeExpenseCurrency((Currency) entryInTransaction
183:                                            .getCommodity());
184:                        }
185:
186:                        return entryInTransaction;
187:                    }
188:
189:                    private void setNewEntryProperties(Entry newEntry) {
190:                        // It is assumed that the entry is in a data manager that is a direct
191:                        // child of the data manager that contains the account.
192:                        TransactionManager tm = (TransactionManager) newEntry
193:                                .getDataManager();
194:                        newEntry.setAccount(tm.getCopyInTransaction(fPage
195:                                .getAccount()));
196:                    }
197:                };
198:
199:                // Load the 'reconcile' indicator
200:                URL installURL = ReconciliationPlugin.getDefault().getBundle()
201:                        .getEntry("/icons/reconcile.gif");
202:                final Image reconcileImage = ImageDescriptor.createFromURL(
203:                        installURL).createImage();
204:                parent.addDisposeListener(new DisposeListener() {
205:                    public void widgetDisposed(DisposeEvent e) {
206:                        reconcileImage.dispose();
207:                    }
208:                });
209:
210:                CellBlock<EntryData, EntryRowControl> reconcileButton = new CellBlock<EntryData, EntryRowControl>(
211:                        20, 0) {
212:                    @Override
213:                    public ICellControl<EntryData> createCellControl(
214:                            Composite parent, final EntryRowControl rowControl) {
215:                        ButtonCellControl cellControl = new ButtonCellControl(
216:                                rowControl, reconcileImage,
217:                                "Reconcile this Entry to the above Statement") {
218:                            @Override
219:                            protected void run(EntryRowControl rowControl) {
220:                                reconcileEntry(rowControl);
221:                            }
222:                        };
223:
224:                        // Allow entries in the account to be moved from the unreconciled list
225:                        final DragSource dragSource = new DragSource(
226:                                cellControl.getControl(), DND.DROP_MOVE);
227:
228:                        // Provide data using a local reference only (can only drag and drop
229:                        // within the Java VM)
230:                        Transfer[] types = new Transfer[] { LocalSelectionTransfer
231:                                .getTransfer() };
232:                        dragSource.setTransfer(types);
233:
234:                        dragSource.addDragListener(new DragSourceListener() {
235:                            public void dragStart(DragSourceEvent event) {
236:                                Entry uncommittedEntry = rowControl
237:                                        .getUncommittedEntryData().getEntry();
238:                                UncommittedObjectKey uncommittedKey = (UncommittedObjectKey) uncommittedEntry
239:                                        .getObjectKey();
240:
241:                                // Allow a drag in all cases except where this entry is a new uncommitted entry.
242:                                // TODO: What if there are uncommitted changes????
243:                                // We should probably commit changes first.
244:                                // We can't drag these because the merge is done by re-parenting.
245:                                if (uncommittedKey.getCommittedObjectKey() == null) {
246:                                    event.doit = false;
247:                                }
248:                            }
249:
250:                            public void dragSetData(DragSourceEvent event) {
251:                                // Provide the data of the requested type.
252:                                if (LocalSelectionTransfer.getTransfer()
253:                                        .isSupportedType(event.dataType)) {
254:                                    Entry uncommittedEntry = rowControl
255:                                            .getUncommittedEntryData()
256:                                            .getEntry();
257:                                    UncommittedObjectKey uncommittedKey = (UncommittedObjectKey) uncommittedEntry
258:                                            .getObjectKey();
259:                                    Object sourceEntry = uncommittedKey
260:                                            .getCommittedObjectKey()
261:                                            .getObject();
262:                                    LocalSelectionTransfer.getTransfer()
263:                                            .setSelection(
264:                                                    new StructuredSelection(
265:                                                            sourceEntry));
266:                                }
267:                            }
268:
269:                            public void dragFinished(DragSourceEvent event) {
270:                                if (event.detail == DND.DROP_MOVE) {
271:                                    /*
272:                                     * Having moved the entry, we must delete this one.
273:                                     * However, this is done as a single operation with
274:                                     * the merge process (so it all appears as a single
275:                                     * undoable/redoable operation). Thus we have
276:                                     * nothing to do here.
277:                                     */
278:                                }
279:                            }
280:                        });
281:
282:                        fUnreconciledEntriesControl
283:                                .addDisposeListener(new DisposeListener() {
284:                                    public void widgetDisposed(DisposeEvent e) {
285:                                        dragSource.dispose();
286:                                    }
287:                                });
288:
289:                        return cellControl;
290:                    }
291:
292:                    @Override
293:                    public void createHeaderControls(Composite parent,
294:                            EntryData entryData) {
295:                        // All CellBlock implementations must create a control because
296:                        // the header and rows must match.
297:                        // Maybe these objects could just point to the header
298:                        // controls, in which case this would not be necessary.
299:                        // Note also we use Label, not an empty Composite,
300:                        // because we don't want a preferred height that is higher
301:                        // than the labels.
302:                        new Label(parent, SWT.NONE);
303:                    }
304:                };
305:
306:                IndividualBlock<EntryData, Composite> transactionDateColumn = PropertyBlock
307:                        .createTransactionColumn(TransactionInfo
308:                                .getDateAccessor());
309:                CellBlock<EntryData, BaseEntryRowControl> debitColumnManager = DebitAndCreditColumns
310:                        .createDebitColumn(fPage.getAccount().getCurrency());
311:                CellBlock<EntryData, BaseEntryRowControl> creditColumnManager = DebitAndCreditColumns
312:                        .createCreditColumn(fPage.getAccount().getCurrency());
313:                CellBlock<EntryData, BaseEntryRowControl> balanceColumnManager = new BalanceColumn(
314:                        fPage.getAccount().getCurrency());
315:
316:                /*
317:                 * Setup the layout structure of the header and rows.
318:                 */
319:                Block<EntryData, EntryRowControl> rootBlock = new HorizontalBlock<EntryData, EntryRowControl>(
320:                        reconcileButton,
321:                        transactionDateColumn,
322:                        PropertyBlock.createEntryColumn(EntryInfo
323:                                .getValutaAccessor()),
324:                        PropertyBlock.createEntryColumn(EntryInfo
325:                                .getCheckAccessor()),
326:                        PropertyBlock.createEntryColumn(EntryInfo
327:                                .getMemoAccessor()),
328:                        new OtherEntriesButton(
329:                                new HorizontalBlock<Entry, SplitEntryRowControl>(
330:                                        new SingleOtherEntryPropertyBlock(
331:                                                EntryInfo.getAccountAccessor()),
332:                                        new SingleOtherEntryPropertyBlock(
333:                                                EntryInfo.getMemoAccessor(),
334:                                                JMoneyPlugin
335:                                                        .getResourceString("Entry.description")),
336:                                        new SingleOtherEntryPropertyBlock(
337:                                                EntryInfo.getAmountAccessor()))),
338:                        debitColumnManager, creditColumnManager,
339:                        balanceColumnManager);
340:
341:                // Create the table control.
342:                IRowProvider rowProvider = new ReusableRowProvider(rootBlock);
343:                fUnreconciledEntriesControl = new EntriesTable<EntryData>(
344:                        getSection(), toolkit, rootBlock,
345:                        unreconciledTableContents, rowProvider, fPage
346:                                .getAccount().getSession(),
347:                        transactionDateColumn, rowTracker) {
348:                    @Override
349:                    protected EntryData createEntryRowInput(Entry entry) {
350:                        return new EntryData(entry, session.getDataManager());
351:                    }
352:
353:                    @Override
354:                    protected EntryData createNewEntryRowInput() {
355:                        return new EntryData(null, session.getDataManager());
356:                    }
357:                };
358:
359:                getSection().setClient(fUnreconciledEntriesControl);
360:                toolkit.paintBordersFor(fUnreconciledEntriesControl);
361:                refresh();
362:            }
363:
364:            public void reconcileEntry(EntryRowControl rowControl) {
365:                if (fPage.getStatement() != null) {
366:                    Entry entry = rowControl.getUncommittedTopEntry();
367:
368:                    // TODO: What do we do about the blank entry???
369:
370:                    /*
371:                     * It is possible that the user has made changes to this entry
372:                     * that have not yet been committed.  Furthermore, those changes
373:                     * may have put the entry into an invalid state that prevents them
374:                     * from being committed.
375:                     * 
376:                     * As validation is done at commit time, we can only set the entry as
377:                     * reconciled and then attempt to commit it.
378:                     */
379:
380:                    // The EntriesTree control will always validate and commit
381:                    // any outstanding changes before firing a default selection
382:                    // event.  We set the property to put the entry into the
383:                    // statement and immediately commit the change.
384:                    if (entry != null) {
385:                        entry.setPropertyValue(ReconciliationEntryInfo
386:                                .getStatementAccessor(), fPage.getStatement());
387:
388:                        /*
389:                         * We tell the row control to commit its changes. These changes
390:                         * include the above change. They may also include prior changes
391:                         * made by the user.
392:                         * 
393:                         * The tables and controls in this editor should all be capable of
394:                         * updating themselves correctly when the change is committed. There
395:                         * is a listener that is listening for changes to the committed data
396:                         * and this listener should ensure all is updated appropriately,
397:                         * just as though the change came from outside this view. However,
398:                         * we must go through the row control to commit the changes. This
399:                         * ensures that the row control knows that its changes are being
400:                         * committed and it does not get confused when the listener
401:                         * processes the changes.
402:                         */
403:                        rowControl.commitChanges("Reconcile Entry");
404:                    }
405:                } else {
406:                    MessageDialog
407:                            .openError(
408:                                    getSection().getShell(),
409:                                    "Action is Not Available",
410:                                    "You must select a statement first before you can reconcile an entry.  The entry will then reconcile to the statement in the upper table.");
411:                }
412:            }
413:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.