GnuCash Project Goals

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.

  1. Architectural Goals
  2. Feature Requirements
  3. Features

Architectural Goals

There are some over-reaching design principles and philosophies that we intend to maintain. Some of these concepts and terms are introduced in this section.

Separation of GUI and Data

First, we must maintain a clean separation between the data structures and the GUI that manipulates them, along the lines of the Model-View-Controller paradigm.

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.

The Financial Engine

In GnuCash, the Model is implemented via the Engine API, and the View is the data that is currently in the Engine. Thus, the Engine is a set of programming API's that the GUI (or a script, or even a clever command-line-addict) can use to manipulate the data.

Currently, the Engine is fairly poor, and is tightly tied to the data structures that the GUI manipulates. These data structures include:

The Engine has a very simple apply/commit model, and a simple query mechanism for generating reports and views.

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.

Modularity, Extensibility and Customization

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.

Markets and Users

Implicit in this desire for extensibility is the need to build financial applications supporting two major classes of users: They may use some of the same financial terminology, and hopefully might share a fair bit of code, but have quite different goals and requirements.

Personal Finance Needs

Important properties of a personal finance system include:

Small Business Needs

Reconciling Those Needs

A seemingly contradictory factor is that the kinds of sophistication that are required vary considerably. Consider:

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.

Feature Requirements

Personal Financial Application

Below are listed the technical work items needed to implement the features that home users might hope to have. They are listed in approximate order of priority.

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

Small Business Features

Features that small/medium businesses expect.
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

Features and Functions

Internationalization
All menus, markup and help-text should be internationalized, so that GnuCash may be usable in any country. This would include the printing of currency values in the local country conventions.

Current status:

Graphs, Reports
Add a variety of reports, including Net Worth, Balance Sheets, and Profit and Loss statements. These should be printable: it might be best to create them as ordinary HTML pages, and use the printing abilities of the browser. These should be easy to customize. Ideally, even novice users should be able to create custom reports.

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:

Simplified Stock Ledger
Stocks and Mutual funds are handled by placing them each in their own account. Each account can be viewed individually. If all of the stock accounts are children of a master trading account, then the trading account can be viewed and modified in a General Ledger window. The current stock general ledger window is a bit obtuse, and difficult to understand and use. A simplified but still powerful ledger window is desperately needed.

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 ...

Themes, Icons, Glitz
A variety of finer touches need work:

Books, Accounting Periods
Ability to close the book at end of the fiscal year.

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...

Check Printing
Create a check-printing ability.
User Preferences
Create menu system and file format for manipulating user preferences.

Preferences include things like showing/not showing categories, forcing double-entry, etc.

Current status:

Extension Language Support
The application is wired together partly with C, partly with Scheme. The architecture of the wiring and how scheme is fit in needs to be reviewed, with a general overview created so that additional extensions may be added in a straightforward manner.

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:

Bonds and Interest Bearing Instruments
Support should be added for Mortgages, Bonds, CD's and other instruments (e.g. savings accounts) that pay interest on a regular basis. It should be possible to specify the interest rate, the payment schedule, and other regularly recurring transactions.

This should be handled by having a way of bouncing out to some Guile code to generate transactions with computed values.

401(k), RRSP
Retirement Savings Plans often do not put a high priority on tracking costs, as the tax implication is that amounts are taxable upon withdrawal, meaning that there is little necessity to track capital gains.
Annotate with News Stories
Download, save, annotate investment news and research. Provide a way of storing news stories with accounts, and possibly annotating individual transactions in the same way.

Loan and Mortgage Calculators
Provide a variety of simple GUI utilities to allow user to calculate the future value of loans, mortgage payments, interest payments, etc.

Status:

Alerts, Recurring Transactions
Provide pop-up notification of deadlines, events, upcoming payments.

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:

Budgeting
Ability to create a budget (i.e. estimates of future expenditures). Reconcile actual expenditures against future expenditures. Create simple, step-by-step 'financial plan' budgeting GUI's: Create a summary budget/track-record budget report that a professional financial planner/advisor could use.

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:

Quicken(TM) Export
Ability to export Quicken QIF files. Quicken import is implemented and mostly works.

Stock Quotes, Price Quotes
Add ability to download stock quotes, other price quotes. Add ability to download historical prices as well. (e.g. get 5-year history of mutual fund performance vs. djia).

Status:

OFX support
Provide the SGML DTD parsers to handle the OFX reports that many banking institutions are providing, or will soon be providing, to retail customers. See below for OFX references.

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.

The other method would be to perform run-time DTD parsing. This is attractive particularly because it is a more commonly-used approach; there are a variety of XML tools available that provide this function.

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.

Multiple Currencies
Need to support multiple currencies. Work is needed in the and the GUI. The engine currently supports multiple currencies by treating them as securities, and thus allowing currency trading. The currency-trading register needs a complete overhaul.

Forced Double-Entry
The system supports double-entry: every transaction indicates a pair of accounts: one is debited, and one is credited.

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:

Tab-delimited ASCII file format
People like to be able to read file contents in ASCII; there are many Unix tools for manipulating ASCII. An ASCII equivalent of the current file format should be easy to develop ... just substitute the writes with printf()s.

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.

Tax Preparation
Gotta prepare those taxes.
Sync with Palm Pilot organizers
There are Quicken-workalikes that run on the PalmComputing platform; it would be good to interoperate with this.
Emergency Records Organizer
Put together a single-page report showing critical info about accounts, etc.

Enriched Engine, Financial Objects
The current system makes a distinction between the data (account, transaction) and they GUI that displays it. The data is embedded within and controlled by the "Engine", which is a set of routines to access accounts, transactions, etc. The engine serves as a kind of a dynamic cache between the permanent data repository (file, sql db) and the GUI.

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.

Current Status:

SQL I/O
A module is necessary to allow data to be fetched from an SQL database, and for that database to be updated. Some thoughts: SQL databases do not need to be locked during editing: instead, an optimistic approach, similar to that employed by CVS (concurrent version system, a mechanism for storing versions of source code) could be used: if the edits conflict with changes made by others, the edit could be rejected en-masse, allowing the user to merge and correct their changes. This is a very important note: updating SQL does NOT require locks to be held for long periods of time!

There has been much discussion about this on mailing lists both for GnuCash and CBB. Major points have included:

Multi-user Support
Multi-user support should be added with either an SQL backend to the engine, and/or through CORBA interfaces to the engine. Project Kontor and also FreeMoney is working on SQL schemas; Kontor is also working on Java RMI/CORBA interfaces. Another possibility is to create a web-application-server, and have users do much/most of I/O with a web interface, possibly using the register object as a browser plugin.

The following industrial-strength features are needed:

Accounts Payable, Receivable
Add features to track sales receipts and other pending sources of income, as well as owed sums.
Payroll
Payroll introduces a sizable amount of complexity in terms of the need to comply with constantly-changing government regulations in whatever country one is in.

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.

Invoicing
Invoicing.
Job Costing
Ability to prepare and track estimates.
Expense Accounts
Expense Account Automation, including air, car, hotel, dining. Receipts, reservations, cancellations.

References


Draft version 0.35 -- November 1999

Linas Vepstas linas@linas.org


Revised December 1999

Christopher Browne cbbrowne@ntlug.org