The people behind GnuCash aim to create a world-class GPL'ed Open Source Personal Financial Application for GNU/Linux and other Unix's. This page aims to review some of the technical and development issues surrounding this product, representing a sort of FAQ for developers and contributors, to suggest directions when developers are trying to determine how to implement new functionality.
To get a better idea of what GnuCash is and what it does, visit its home page.
There are currently several different versions of GnuCash.
The latest Gnome version, and latest versions in general, are currently available only via CVS.
Precompiled versions are available, but usually only for the stable releases. Don't use the unstable versions unless you are ready for excitement and adventure, and are prepared to cope with a need to keep extensive backups.
This document is divided into several sections.
Thus, the Motif or Gnome GUIs are merely two possible manipulators of the data; others, based on e.g. Qt/KDE, emacs, Java applets or Java servlets ought to be possible.
GnuCash also needs to deal with multiple distributed data sources: stock quotations from the net or transaction confirmations from online banks and brokerage houses, or from more mundane sources, such as file imports, or merger of data from several users.
Amongst these terms, the concept of a global Model-View is dated, and somewhat inappropriate. Rather, we need to be concerned about how data is represented in the local address space of the GUI, how the GUI manipulates it, how data is brought in and merged from external sources, and how that data is again output, whether to a file or a local or remote database.
Thus, the View essentially represents a local data cache of the data that is immediately present and being displayed, reported, and manipulated. The Model is the abstraction of that data that the GUI (the controller) can act on.
Currently, the Engine is fairly poor, and is tightly tied to the data structures that the GUI manipulates. These data structures include:
The Engine currently handles only a small set of data sources:
However, since the Engine is meant to be the interface between the GUI and the financial data, it is really intended to be able to do much more.
In particular, it should be possible to back the Engine onto an SQL database, and thereby enable multiple users and/or interface to more complex accounting systems. The engine should also be expandable to handle other sources of data, such as OFX, Integrion GOLD, the Open Trading Protocol, the OMG CORBA General Ledger submission, the IBM San Francisco business objects, or closer to home, Linux Kontor. In particular, it should be possible to use GnuCash not only to view data from these sources, but also to manipulate it and send it back.
The above structure should leads us to view GnuCash not so much as a tightly integrated application, but rather as a loose confederation of component objects, libraries and interfaces.
In order to facilitate the gluing together of these parts, as well as simplify the questions of customizability, change and rapid development, GnuCash makes use of an extension language to glue the pieces together.
The extension language that is most central to Gnucash is Scheme, and in particular, the FSF implementation, Guile, although some of the interfaces are also available through Perl.
Important properties of a personal finance system include:
A seemingly contradictory factor is that the kinds of sophistication that are required vary considerably. Consider:
Thus, home users don't need much of the sophistication of an Accounts Receivable or Payable system, or the bizarre depreciation policies that crop up in Asset Management systems.
It may be that these will require completely different systems, and that GnuCash cannot be "all things to all people." This remains to be seen.
The right hand column shows a sizing guesstimate. pm == person-months
Feature | Sizing |
---|---|
Internationalization | Small |
Graphs, Reports | Medium |
Simplified Stock Ledger | Small |
Themes, Icons, Glitz | Medium |
Books, Accounting Periods | Small |
Check Printing | Small |
User Preferences | Medium |
Extension Language Support | Medium |
Bonds and Interest Bearing Instruments | Small |
401K etc. | Small |
Annotate with Investment News | Small |
Loan and Mortgage Calculators | Small |
Budgeting | Medium |
Alerts, Recurring Transactions | Medium |
Quicken(TM) Export | Small |
Stock Quotes, Price Quotes | Small |
OFX, Online Banking, Trading, Billpay | Large |
Multiple Currencies | Medium |
Double Entry Accounting | Small |
Tab-delimited ASCII export | Small |
Tax Preparation | Large |
Sync with Palm Pilot organizers | Medium |
Emergency Records Organizer | Small |
Feature | Sizing |
---|---|
Enhanced Engine, Financial Objects | Large |
SQL I/O | Medium |
Multi-User Support | Medium |
A/R, A/P Accounts Payable, Receivable | Medium |
Payroll | Medium |
Invoicing | Medium |
Job Costing | Medium |
Expense Accounts | Large |
Current status:
Other output format possibilities include SGML and Extensible Markup Language - XML. In the long run, these are preferable to HTML, since DSSSL tools such as Jade (James DSSSL Engine) can be used to convert to RTF, Postscript, etc.
Add to this the consideration that XML is the basis for the Document Object Model, which is being integrated into many web-based applications, and we can see that XML is an increasingly significant format as we look to the future.
The Report Generator should be a separate but "dockable" subsystem of the whole.
Thus, it should be possible to run the report generator in a stand-alone, read-only fashion without having to start up the main application.
Graphs, charts, etc. too ...
Asset allocation pie chart.
Graph portfolio value vs. cost
One difficult aspect of reporting is designing a configurable interface, so that people can build custom reports. The New Reporting Infrastructure is seeking to build this up using Guile.
Stock portfolio tools should include a Cost Averaging report, Market Index report, Stock Option values, Estimation of capital gains tax liabilities.
Status:
Question: How to most simply allow the user to enter loads and fees?
Answer: Through splits. Unfortunately, some users may not properly understand splits, at least not initially. Thus, a little popup is needed to allow the user to type in the sales load or fee and such, and then auto-create the needed splits.
Note the current transfer window does NOT allow a share price to be specified !! Needs fixing ...
A set of themes would be desirable for the Gnome version.
A user-configurable button-bar would be nice too.
Provide a default list of "Categories" (Income/Expense Accounts). These are categories such as "Automobile Expense", "Bank Interest Income", and "Employment Income". The user should be able to select a default set of accounts, and have those created automatically.
To actually implement this, it might be best to simply create a file with these in them, and load that file. A mechanism should be provided to allow the user to weed out undesired accounts whilst not preventing them from using them at a later date, if desired.
Add an example showing how regular household assets (house, car, jewelry, etc.) should be treated. In particular, show how appreciation and depreciation should be treated.
Menu navigation using the keyboard should be possible.
Although menu mnemonics exist, they seem to be broken.
Similarly, tab-key navigation should be possible. Currently, it is possible to use the tab key to navigate from field to field in the register window, to user arrow keys to navigate menus, and quick-fill to automatically complete fields. However, it is not possible to tab over to the "Commit" button.
It should be.
Currently, Income/Expense accounts can be shown or hidden by selecting from a menu. It would be nice to be able to examine different account types (Asset, Liability, Income, Expense, Payables, Receivables, Inventory) by selecting a tab folder.
When the user pauses the mouse over a button, "fly-over" pop-up help windows should appear.
Create grayed out entries in the ledger, titled "Memo", "Description", etc, helping users understand what should be typed into each field.
Make sure that text fields can handle the vi and emacs key bindings, so that e.g. emacs-style ctrl-a, ctrl-k does the right thing.
i.e. Ability to permanently lock records as non-editable. This should be straight-forward by using the reconciled field to indicate a locked value, and not allowing the GUI to edit locked records.
Also need to report closed books slightly differently. Need to bring balances forward too...
Preferences include things like showing/not showing categories, forcing double-entry, etc.
Current status:
The overall architecture is envisioned thus:
All code, including the transaction engine, the file I/O routines, the menus, and the ledger, will be abstracted into compact modules that can function independently of each other. At the highest level, there will be a infrastructure with extension language interfaces that will "wire together" the various modules.
Such "wiring together" will consist of a dispatch infrastructure that will allow arbitrary menu entries to be hooked to arbitrary modules. The configuration for menu entries, and their associated callbacks, will be specified in an extension-language configuration file. At the final stages, it is highly desirable to be able to, in some manner, import new modules without requiring that the application itself be recompiled and relinked.
Status:
This should be handled by having a way of bouncing out to some Guile code to generate transactions with computed values.
Status:
Add support for automatic, recurring transactions, e.g. mortgage payments, fixed-interest bonds, bank accounts, etc.
Note that the design for this could be very different, depending on whether the multi-user functions are available or not.
Design/implementation for this is tricky. It should probably leverage crontab, but this can lead to difficulties and bugs.
May need interfaces to email for emailed alerts.
Interfaces into calendaring systems? Current status:
Note that the above 'step-by-step' budgeters will have a very very different GUI than what the budgeting system required for a small-business might look like.
Status:
Status:
Right now, this is a stand-alone perl script run from crontab.
OFX is an open spec from Microsoft, Intuit, and Checkfree, and which will be supported by Integrion. The OFX DTD's are included in the 1.1 distributions. See OFX Home Page for details.
There are two ways to build an OFX parser. One way is to build a compile-time DTD parser that treats the DTD as if it were an IDL, and generates C language stubs for a parser.
This approach was attempted and abandoned because it leads to fragile C code and a very large binary.
Run-time parsing may be slower, but on the OFX client side, this should not be a bottleneck.
Status:
Note that the organizations developing OFX are looking to use XML as their "formats of the future;" this may encourage the use of one of the many XML parsers available for UNIX.
Double-entry is a powerful way of ensuring the integrity of of the financial data. Currently, while double-entry is supported, its use is not enforced: the user can create dangling transactions, where only one account is indicated.
Although this is acceptable for home use (even desirable, since it allows the casual user the simplicity they desire), it is not acceptable for business use.
It must be possible to enable forced-double entry, so that a transaction cannot be completed until two accounts have been specified.
Current status:
The tab-delimited format should be compatible with that of /rdb, aka RAND/Hobbs /rdb or NoSQL. (NoSQL is available as part of the Debian GNU/Linux distribution, for instance.)
The /rdb format is thus:
field-name tab fieldname tab fieldname \n ------------------------------------------ \n value tab value tab value \n value tab value tab value \n etc ...
It is a very simple, very basic flat table format. The use of /rdb with GnuCash should try to match with SQL schemas as much as possible in order to minimize I/O complexity and incompatibility.
categorize items according to different tax schedules
The current engine is rather simple: it provides support for accounts, account hierarchies and transactions consisting of multiple entries.
Many of the features described elsewhere will require that the engine have a far richer, more sophisticated data model, including such things as:
Note: it makes no sense at this point to make the engine API much richer than what the GUI can currently support.
In a business environment, the auditors may have "signed off" on the validity of the data; at that point, the ability to modify audited data should be very tightly controlled, or even downright forbidden.
Current Status:
These "Transaction processing constructs" should simplify creation of an SQL back end, or some other more sophisticated database engine.
There has been much discussion about this on mailing lists both for GnuCash and CBB. Major points have included:
This may be a minor cost to a business enterprise that hires DataBase Administrators.
It is not acceptable to require this of naive users that may find "simple" things like
% su - Password: # cd /tmp # rpm -i gnucash-4.1.3.i386.rpm # exitto be challenging.
Changing GnuCash to be suited to use a DBMS in other than a "load-it-all" / "dump-it-all" manner, but to rather update the database in a transactional manner.
That being said, it may be possible to recast the GnuCash engine functionality so as to handle storage in a transactional manner.
The following industrial-strength features are needed:
While the GnuCash "engine" might remain free, maintenance of payroll functionality would require "subscribing" to an update scheme; it might be troublesome to try to provide such a "subscription" free of charge.
Mostly aimed at mainframes, middleware, high transaction volumes and data integrity.
Linas Vepstas
linas@linas.org
Christopher Browne
cbbrowne@ntlug.org