|
|
GNUCash (http://www.gnucash.org) is distributed under GPL. It’s focused on personal finance like Quicken/MS Money but can also be used for small business accounting.
GnuCash is written primarily in two languages: C and Scheme. The
engine/server is written in C primarily for speed, portability,
stability and historical reasons. Various bits and pieces that help
glue together the various components are written in Scheme. Scheme was
chosen for its power, expressiveness and ease of development. The user
interface uses the GTK/Gnome widget set, and is designed primarily with
the Glade GUI designer tool. The file format is in XML, and multi-user
support is provided through the Postgres SQL backend. The reporting
subsystem, written in Scheme, generates HTML reports.
For an overview of the architecture see http://www.gnucash.org/en/architecture.phtml
GNUCash consists of ten modules:
(1) Engine
The Engine (located under the src/engine/ directory in the GnuCash
codebase) provides an interface for creating, manipulating, and
destroying five basic financial entities: Accounts, Transactions (known
as Ledger Entries in accounting practice), Splits (known as Journal
Entries), Prices and Lots. These five entities provide the central data
structures of the GnuCash financial data model. The Engine code
contains no GUI code whatsoever, and is essentially OS-neutral. It is
written entirely in C.
(2) Query
The Query module (also in src/engine/) provides a generic mechanism for
performing complex, structured queries on a collection of objects. For
example, GnuCash uses queries to find transactions based on a set of
user-specified criteria, such as description, date posted, account
membership, etc. Simple queries can be combined using standard Boolean
operators. The query subsystem is a true generic object-query system,
independent of the financial structure in GnuCash, and is slowly being
spun-out as a stand-alone component at qof.sourceforge.net. Note that
Query works closely with the data storage backend, so that the local
collection of objects in the GnuCash engine acts as a 'cache' for a
possibly much larger set of data in the SQL backend. The idea is to
keep GnuCash 'scalable': the runtime size can stay small, while still
having high-performance interactions, even when dealing with large,
remote databases.
(3) Storage Backend
The Storage Backend module (src/backend/) defines a generic interface
for storing GnuCash data (into files or databases) or for communicating
with a remote GnuCash storage server (by any server-defined protocol).
Currently implemented and supported are the XML file backend, which
stores GnuCash data in its native XML file format, and the Postgres SQL
backend, which supports multiple simultaneous users of GnuCash.
Additionally, there are several experimental backends (currently
broken/unsupported): one for communicating with a GnuCash storage
server via RPC, and another that chats, via XML across HTTP, with a
GnuCash server.
(4) Register
The Register (src/register/) implements a ledger-like GUI that allows
the user to dynamically enter dates, prices, memos descriptions, etc.
in an intuitive fashion that should be obvious to anyone who's used a
checkbook register. The code is highly configurable, allowing the
ledger columns and rows to be laid out in any way, with no restrictions
on the function, type, and number of columns/rows. For example, one can
define a ledger with three date fields, one price field, and four memo
fields in a straightforward fashion. Cell handling objects support and
automatically validate date entry, memo entry (w/auto-completion),
prices, combo-boxes (pull-down menus), and multi-state check-boxes.
Cells can be marked read-write, or output-only. Cells can be assigned
unique colors. The currently active ledger row-block can be highlighted
with a unique color.
The register code is completely independent of the engine code, knows
nothing about accounting or any of the other GnuCash subsystems. It can
be used in independent projects that have nothing to do with
accounting.
(5) Reports and Graphs
The Reports & Graphs module (src/report/) is a scheme (guile) based
system to create balance sheets, profit & loss statements, barcharts,
piecharts, etc. It uses the Query API to fetch and format data, which
is then converted into HTML and displayed with the gtkhtml widget.
Graphs are implemented in Guppi, (http://www.gnome.org/guppi) and are
embedded (as live graphs) directly in the HTML.
(6) User Preferences
The User Preferences module (src/app-utils/) provides an infrastructure
for defining both user-configurable and internal preferences.
Preferences are defined in scheme using several predefined preference
types such as boolean, string, date, etc. Preferences are 'implemented'
by providing a GUI which allows the user to see and change preference
values. An API is provided to query preference values and to register
callbacks which will be invoked when preferences change.
Preference values which are different from the default values are
stored as scheme forms in a user-specific preferences file
(~/.gnucash/config.auto). This file is automatically loaded upon
startup.
(7) Data Import and Export
The Import module (src/import-export/) provides functionality for
importing QIF (Quicken Interchange Format) data files and OFX (Open
Financial Exchange) files into GnuCash. One of the difficult aspects of
importing data from a file is what to do if the file contains some data
that has already been entered into GnuCash. This can happen when the
imported file is a bank statement obtained periodically from a website:
each time it is fetched, it might contain transactions that were
previously reported. Thus, to perform file import correctly, one must
have a fairly sophisticated transaction matcher that can detect and
properly handle (ignore) duplicate transactions. This pattern matching
is generically useful, and is used by the HCBI subsystem. (HCBI is an
online banking system available to residents of Germany).
(8) Small Business Features
GnuCash provides support for a number of business features
(src/business/). This module is not described in detail.
(9) Recurring Transactions
Scheduled transactions provide a mechanism for describing a set of
regularly recurring financial transactions so that the GnuCash dataset
can be automatically updated as time passes. This module is not
described in detail.
(10) GnuCash
The GnuCash module (src/gnome and other directories) is the main GUI
application. It consists of a collection of miscellaneous GUI code to
glue together all of the pieces above into a coherent, point-and-click
whole. It is meant to be easy to use and intuitive to the novice user
without sacrificing the power and flexibility that a professional might
expect. When people say that GnuCash is trying to be a "Quicken or MS
Money look/work/act-alike", this is the piece that they are referring
to. It really is meant to be a personal-finance manager with enough
power for the power user and the ease of use for the beginner.
Currently, the Gnome interface is the only operational interface. An
obsolete Motif interface can be fished out of historical CVS; but this
interface has been deleted in the current CVS.
Architectural Goals
There are some over-reaching design principles and philosophies that
the GNUCash group intends to maintain.
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.
- Lists of accounts and the transactions in them can be thought of as a representation of financial data, a Model.
- The GUI that adds, modifies and deletes these should be thought of as a manipulator of the data, a Controller. Thus, the Motif or Gnome GUI's are merely two possible manipulators of the data; others, based on e.g. web/cgi-bin, Qt/KDE, emacs, Java applets or Java servlets ought to be possible.
- The View of the data is a subset or slice of the data described by the Model. The View may consist of only the transactions for the month of May, or only the account totals for certain accounts. The View is used in part to generate the reports and graphs, but it is also that which the Controller interacts with. Views are generated by queries to the data store.
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 provides basic accounting structures. These include:
- Transactions, which consist of a set of 'splits' or journal entries (JE's) whose values sum to zero. The transaction includes several date fields, a description, and a common-currency field, and a universal unique id (uuid/guid). It also provides hooks to store arbitrary data associated with the transaction (using a URL-based key-value tree).
- Journal Entries (internally referred to as 'splits') which an amount and the account on which it is drawn. Splits also store reconcile status, dates, a memo field, and also a key-value based hook for arbitrary data.
- Accounts, which include a name, a type, a description field, and the type of commodity they store. Principally, the account consists of a list of journal entries.
- Chart of Accounts, which is a hierarchical tree of accounts.
The Engine has a basic two-phase commit model, and a query mechanism
for finding the data needed for reports and views. The goal of the
two-phase commit and query model is allow the creation of multi-user
server based backends, such as an SQL backend, and RPC client-server
backend, or an XML-based HTTP/web backend. This design seems to work
for the above-named backends.
The Engine currently handles only a basic set of data sources:
- It can import and merge in QIF's (actually, this function has been moved into the GUI, and is no longer part of the engine);
- It can read and write its own XML byte stream; This ability has been used to provide a multi-user client-server demo (which is currently broken).
- It can use a Postgres SQL database as a datastore, thereby enabling multi-user and auditing functions.
- It can talk, via RPC, to a gnucash server. (This code is 'alpha' and incomplete/broken).
- It can get stock quotes from the net (actually, this function is provided by a separate module, the Finance::Quote perl module.) 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 create a peer-to-peer network model, where gnucash peers can synchronize data between
themselves. The engine should also be expandable to handle other sources of data, such as OFX/IFX, the Open Trading Protocol, or the OMG CORBA General Ledger submission. 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 lead us to view GnuCash not so much as a
tightly integrated application, but rather as a loose confederation of
component objects, libraries and interfaces. This has a number of
advantages for both the developer and the user. For the developer, it
allows parts to evolve semi-independently of one-another, and to be
used in other, non-gnucash projects. For the user, a good extensibility
allows the use of arrangements: a way of broadly customizing the
appearance and behavior of gnucash, and then allowing users to very
easily share these customizations with one another. Such arrangements
might be collections of canned reports, e.g. for business or home user.
Or they might be the menu contents: one menu arrangement is for
beginners, another for 'power users', a third for business owners. The
goal is that broad areas should be not only customizable, but it should
be possible, even easy, to trade these customizations between users.
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 the Scheme extension language (as
implemented in the FSF Guile interpreter), to glue the pieces together.
(Note that the engine interface is also available with Perl interfaces,
thanks to a SWIG wrapper.
A Web Browser for Financial Data
More and more finacial data is moving onto the web. People shop
on-line. They pay bills on-line. There are even some promising e-wallet
systems (such as WebFunds?). For GnuCash to be relevant in this on-line
world, it must be able to interact with these systems. There are
several steps that can be taken along this path. First, it must be
possible to simply and transparently import financial data off the web.
Click on a QIF file, mime-type "application/x-qif"? Gnucash sucks it in
without burping. But, in a more distant future, can GnuCash originate
transactions? It should be able to!
GnuCash can be and should be "The Sophisticated Financial Web Browser".
All GnuCash reports and the help system are HTML-based. In fact,
GnuCash has a built-in web browser that can view ordinary web sites.
Interactive gnucash components such as the bar and pie charts, or the
graphs and reports, can all be served up by a remote web server, as
well as locally through the GnuCash application. This allows GnuCash to
blur the line between web browser and financial application, and offer
the best of both worlds.
Why is this a good thing? One can always have a pure web-based
accounting solution (such as SQL-Ledger) that uses ordinary web
browsers to view the financial data. But there are problems:
dynamically-generated html and cgi-bins aren't as pretty or easy to
use, or as fast, responsive or sophisticated, as what you can do with a
custom client. That is, GnuCash can be more interactive, easier to
user, slicker and more professional looking in style and presentation
than a plain-old dynamic website. Financial ASP's simply cannot
currently offer the kind of utility, flexibility, responsiveness and
integration that GnuCash can offer.
In theory, the 'Java revolution' was supposed to provide this function,
with downloadable Java applets providing the 'fancier- than-plain-html'
interface. But a Java applet that is this sophisticated would also be
large and slow to download: it offers no inherent advantages over
native code. Another problem with Java is the inherent proprietary
fragmentation: no two Java applets are alike: every site has their own;
there is no standardization.
In order to solve the 'no gui standardization between websites'
problem, there are a number of businesses that have arisen to provide
"financial aggregation". You sign up with these sites, and let them get
all of your credit-card, bank and investment info, and they can provide
a unified interface for your bank statements, with graphs and reports
(all for a monthly fee). The existence of these services highlights a
problem: the inability to aggregate the same data on the users desktop,
in a simple, coherent fashion. Let us posit that GnuCash, with the
right on-line interfaces, would be a natural for this. For the
paranoid, this has the added advantage that no one business has access
to all of your financial records. To put it another way, GnuCash can
provide a centralized, trusted store for financial data that no other
application can provide.
GNUCash project goals, product roadmap, and additional technical
details are at http://linas.org/linux/gnucash/projects.html.
|
|