Doxygen - merge separate txt files into respective header files

This commit is contained in:
Geert Janssens 2024-05-23 11:38:39 +02:00
parent 6cd8e4e458
commit e8d72ad53f
11 changed files with 899 additions and 990 deletions

View File

@ -22,6 +22,135 @@
# @author Jeff Green, ParIT Worker Co-operative <jeff@parit.ca>
# The following is for doxygen
## @defgroup python_bindings Python Bindings Module
# Also have a look at the page @ref python_bindings_page.
## @defgroup python_bindings_examples Python Bindings Examples Module
# @ingroup python_bindings
# The python-bindings come with quite a lot of example scripts.
## @page python_bindings_page Python bindings
# Also have a look at group @ref python_bindings.
#
# In the source tree they are located at bindings/python.
#
# To enable them in the compilation process you have to add -DWITH_PYTHON=ON
# to the call of cmake.
#
# As a starting point have a look at the \link python_bindings_examples example-scripts\endlink.
#
# @section possibilities What can Python Bindings be used for ?
#
# The python bindings supply the ability to access a wide range of the core functions of GnuCash. You
# can read and write Transactions, Commodities, Lots, access the business stuff... You gain the ability
# to manipulate your financial data with a flexible scripting language.
#
# Not everything GnuCash can is possible to access though. The bindings focus on basic accounting functions.
# Have a look at the examples to get an impression.
#
# Some functions are broken because they have not been wrapped properly. They may crash the program or return unaccessible values.
# Please file a bug report if you find one to help support the development process.
#
# @section python_bindings_section Principles
# The python-bindings are generated using SWIG from parts of the source-files of GnuCash.
#
# @note Python-scripts should not be executed while GnuCash runs. GnuCash is designed as
# a single user application with only one program accessing the data at one time. You can force your
# access but that may corrupt data. Maybe one day that may change but for the moment there is no active development on that.
#
# @subsection swigworks What SWIG does
#
# SWIG extracts information from the c-sources and provides access to the structures
# to python. It's work is controlled by interface files :
#
# @li gnucash_core.i
# @li timespec.i
# @li glib.i
# @li @link base-typemaps.i src/base-typemaps.i @endlink This file is shared with Guile.
#
# it outputs:
#
# @li gnucash_core.c
# @li gnucash_core_c.py
#
# If you have generated your own local doxygen documentation (by "make doc") after having compiled the python-bindings, doxygen
# will include SWIGs output-files.
# It's actually quite interesting to have a look at them through doxygen, because they contain all that you can
# access from python.
#
# This c-style-api is the bottom layer. It is a quite raw extract and close to the original source. Some more details are described further down.
#
# For some parts there is a second layer of a nice pythonic interface. It is declared
# in
# @li gnucash_core.py and
# @li gnucash_business.py.
# @li function_class.py contains helper functions for that.
#
# @section howto How to use the Python bindings
# @subsection highlevel High level python wrapper classes
# If you
#
# @code >> import gnucash @endcode
#
# You can access the structures of the high level api. For Example you get a Session object by
#
# @code >> session=gnucash.Session() @endcode
#
# Here you will find easy to use things. But sometimes - and at the current level rather sooner than
# later - you may be forced to search for solutions at the :
#
# @subsection c_style_api C-style-api
#
# If you
#
# @code >> import gnucash @endcode
#
# The c-style-api can be accessed via gnucash.gnucash_core_c. You can have a look at all the possibilities
# at gnucash_core_c.py.
#
# You will find a lot of pointers here which you can just ignore if input and output of the function have the
# same type.
#
# For example you could start a session by gnucash.gnucash_core_c.qof_session_begin(). But if you just try
#
# @code session=gnucash.gnucash_core_c.qof_session_begin() @endcode
#
# you will get an error message and realize the lack of convenience for you have to add the correct function parameters.
#
# Not all of the available structures will work. SWIG just takes everything from the sources that it is fed with and translates it. Not everything
# is a working translation, because not everything has been worked through. At this point you are getting closer to the developers who you can
# contact at the mailing-list gnucash-devel@gnucash.org. There may be a workaround. Maybe the problem can only be fixed by changing SWIGs input
# files to correctly translate the c-source. Feel free to post a question at the developers list. It may awaken the interest of someone who creates
# some more beautiful python-interfaces.
#
# @section Thisorthat When to use which api ?
#
# The start would surely be the high-level api for you can be quite sure to have something working and you will maybe find
# explanations in the example-scripts. If you search for something that is not yet implemented in that way you will have to
# take your way to the c-style-api.
#
# @section pydoc (Further) documentation
#
# @li The documentation you just read uses doxygen. It collects documentation in GnuCash's sources. Besides that there is
# @li the classic python-documentation using help() and docstrings. Have a look at both.
# @li There is a page in the GnuCash wiki at https://wiki.gnucash.org/wiki/Python
# @li You may also have a look into the archives of gnucash-devel@gnucash.org.
# @li On Bugzilla there is also some interesting talk regarding the development process.
# @li Then you can use the abilities of git to see the history of the code by @code git log @endcode done in the directory of the python-bindings.
#
# @section pytodo To-Do
# @li Work out the relation of scheme/guile and python-bindings
# @li maybe join python_bindings_page and group
# @li work on the structure of the documentation to make it more clear
# @li try to make SWIG include the documentation of the c-source
# @li make function-links in SWIG-generated files work.
# @li some words to the tests
#
# @author Christoph Holtermann
# @date December 2010
## @file
# @brief High level python wrapper classes for the core parts of GnuCash
# @author Mark Jenkins, ParIT Worker Co-operative <mark@parit.ca>

View File

@ -4,9 +4,6 @@ set(doc_FILES
doxygen_main_page.c
finderv.html
finutil.html
loans.txt
lots.txt
python-bindings-doxygen.py
README
)

View File

@ -1,288 +0,0 @@
/** \page loanhandling Handling loan repayment in GnuCash::Scheduled Transactions
\sa The original email thread at <https://lists.gnucash.org/pipermail/gnucash-devel/2002-July/006438.html>.
July, 2002 - jsled@asynchronous.org
API: \ref SchedXaction
We define loan repayment values in the following terms:
Identifiers:\n
P : the original principal. This is the overall principal afforded by the
loan at the time of it's creation.\n
P' : The beginning principal. This is the principal at the time of entry
into GnuCash.\n
I : The interest rate associated with the loan. Note that this may change
over time [based on an addition to the Prime rate, for instance], at
various frequencies [yearly, monthly, quarterly...]. Ideally, we can
use the FreqSpec mechanism to facilitate the interest rate adjustment.\n
N : The length of the loan in periods.\n
m : The minimum periodic payment.\n
n : The current period of the repayment.
Functions:\n
PMT : Total equal periodic payment, as per Gnumeric/Excel's definitions
[see end for more detail].\n
IPMT : Monthly payment interest portion, ""\n
PPMT : Monthly payment principal portion, ""
[ NOTE: 'PMT(I,N,P) = IPMT(I, n, N, P) + PPMT(I, n, N, P)' for 0 <= n < N ]
The formula entered into the SX template for a loan may then look like:
Example 1:
\verbatim
Desc/Memo | Account | Credit | Debit
----------+-----------------------------+----------------+-------------------
Repayment | Assets:Bank:Checking | | =PMT(I,n,N,P)
| | | + fixed_amt
Interest | Expenses:Loan_Name:Interest | =IPMT(I,n,N,P) |
PMI | Expenses:Loan_Name:Misc | fixed_amt |
Principal | Liabilities:Loan_Name | =PPMT(I,n,N,P) |
-----------------------------------------------------------------------------
\endverbatim
Or, in the case where an escrow account is involved [with thanks to warlord
for the review and fixes]:
Example 2:
\verbatim
Desc/Memo | Account | Credit | Debit
---------------+-----------------------------+----------------+--------------
Repayment | Assets:Bank:Checking | | =PMT(I,n,N,P)
| | | + escrow_amt
| | | + fixed_amt
| | | + pre_payment
Escrow | Assets:Loan_Escrow_acct | escrow_amt |
Interest | Expenses:Loan_Name:Interest | =IPMT(I,n,N,P) |
PMI | Expenses:Loan_Name:Misc | fixed_amt |
Principal | Liabilities:Loan_Name | =PPMT(I,n,N,P) |
| | + pre_payment |
\endverbatim
FreqSpec = 1 month
\verbatim
-----------------------------------------------------------------------------
Desc/Memo | Account | Credit | Debit
---------------+-----------------------------+----------------+--------------
Insurance | Assets:Loan_Escrow_acct | | insurance_amt
Insurance | Expenses:Home_Insurance | insurance_amt |
\endverbatim
FreqSpec = 1 year
\verbatim
-----------------------------------------------------------------------------
Desc/Memo | Account | Credit | Debit
---------------+-----------------------------+----------------+--------------
Taxes | Assets:Loan_Escrow_acct | | taxes_amt
Taxes | Expenses:Property_Taxes | taxes_amt |
FreqSpec = Quarterly
-----------------------------------------------------------------------------
\endverbatim
\section guidpractical Practical questions regarding the implementation of this facility are:
| 1. The transactions as in Example 2 are not going to be scheduled for the\n
| same day; are their values linked at all / do they need to share the\n
| same var bindings?
Yes, they would want to be linked. More precisely, the insurance/tax amounts
are very likely linked to the escrow_amt in Ex.2. Unfortunately, these are
very likely separate SXes...
-----
| 2. How does this effect the SX implementation of variables?
Vastly.
It becomes clear that multiple SXes will be related. While they'll have
separate FreqSpecs and template transactions, they'll share some state. For
both visualization [i.e., the SX list] and processing [credit/debit cell
value computation] we'll want some manner of dealing with this.
It becomes clear as well that the nature of variables and functions needs to
be more clearly defined with respect to these issues. We probably want to
institute a clear policy for the scoping of variables. As well, since the
SXes will have different instantiation dates, we'll need a method and
implementation for the relation of SXes to each other.
A substantial hurdle is that if a set of SXes are [strongly] related, there
is no-longer a single instantiation date for a set of related SXes. In fact,
there may be different frequencies of recurrence.
One option -- on the surface -- to relate them would be to maintain an
instance variable-binding frame cache, which would store user-entered and
computed variable bindings. The first instantiated SX of the set would create
the frame, and the "last" instance would clean it up. First "last" instance
is defined by the last-occurring SX in a related set, in a given time range.
For example: a loan SX-set is defined by two monthly SXes ["repayment" and
"insurance"], and a quarterly "tax" SX. The first monthly SX would create a
frame, which would be passed two the second monthly SX. This would occur for
the 3 months of interest. The Quarterly SX would get all 3 frames for it's
creation, and use them in an /appropriate/ [read: to be defined through a lot
of pain] way. As the time-based dependency relationship between the frames
plays out, the frame can be removed from the system.
Another option is to toss this idea entirely and instead let the user DTRT
manually.
A related option is to add the necessary grouping mechanism to the SX
storage/data structure: immediately allowing visual grouping of related SXes,
and potentially allowing a storage place for such frame data in the future
with less file-versioning headache. This is the option that will be pursued.
Another element implicit in the original requirements to support
loans/repayment calculations is implicit variables. These are symbolic names
which can be used and are automagically bound to values. The known implicit
variables to support loan/repayment are:
P [loan principal amount], N [loan repayment periods], I [interest], m
[minimum payment] and n [current period]. Some of these [P, N, I, m] are
fixed over many instances; some [n] are rebound specific to the instance.
See the 'variable-scope-frame' below for a method of handling these
variables.
And yet-another element implicit in the original requirement is support for
detecting and computing the result of functions in the template transaction's
credit/debit cells. Changes to the src/app-utils/gnc-exp-parser.[hc] and
src/calculation/expression_parser.[ch] to support functions would be
necessitated. It is conceivable that after parsing, the parsed expression
could be passed to scheme for evaluation. Hopefully this would make it
easier to add support for new functions to the SX code via Scheme.
| 3. How do we deal with periodic [yearly, semi-yearly] updating of various\n
| "fixed" variables?
Another change in the way variables are used is that some SXes -- especially
loan-repayment -- may involve variables which are not tied to the instance of
the SX, but rather to variables which:
- are also involved in another SX
- change with a frequency different than the SX
- are represented by a relationship to the outside world ["prime + 1.7"]
A partial fix for this problem is to provide multiple levels of scope for
variable bindings, and expose this to the user by a method of assigning
[perhaps time-dependent] values to these variables. Variables bound in this
manner would absolve the user of the need to bind them at SX-creation time.
An added benefit of this would be to allow some users [see Bug#85707] have
"fixed variable" values for a group of SXes.
In combination with the SX Grouping, this would provide most of a fix for the
problem described in #2, above. The variable_frame could be used to provide
the shared-state between related SXes, without imposing quite the same
burden. This approach is slightly less flexible, but that allows it to be
implemented more readily, and understood more easily.
A question which comes up when thinking about yearly-changing values such as
interest rates is if the historical information needs to be versioned. For
now, we punt on this issue, but hopefully will provide enough of a framework
for this to be reasonably added in the future.
We define four types of variables supported by this scheme:
implicit : provided only by the system
e.g.: 'n', the current index of the repayment
transient : have user-defined values, bound at instantiation time.
e.g.: existing ad-hoc variables in SXes.
static : have a user-defined values, and are not expected to change with
any measurable frequency. The user may change these at their
leisure, but no facility to assist or encourage this is
provided.
e.g.: paycheck amount, loan principal amount
periodic : have user-defined values which change at specific points in
time [July 1, yearly]. After the expiration of a variable value,
it's re-binding will prevent any dependent SXes from being
created.
e.g.: loan tax amount, loan interest rate
| 4. From where do we get the dollar amount against which to do the [PI]PMT\n
| calculation?
The user will specify the parameters of the Loan via some UI... then where
does the data go?
- KVP data for that account?
- KVP data for the SX?
- Do we have a different top-level "Loan" object?
- Present only in the SX template transactions/variable-frames?
I believe that the only location of the data after Druid creation is in the
variable-binding frames and the formulae in the template transactions. The
Druid would thus simply assist the user in creating the following SX-related
structures:
- SXGroup: Loan Repayment
- variable_frame
- P [static]
- N [static]
- n [implicit]
- I [periodic]
- pmi_amount [periodic]
- tax_amount [periodic]
- pre_payment [periodic]
- insurance_amount [periodic]
- SX: Payment
- Bank -> { Escrow,
Liability:Loan:Principal,
Expense:Loan:Interest,
Expense:Loan:Insurance }
- SX: Tax
- Escrow -> Expense:Tax
- SX: Insurance
- Escrow -> Expense:Insurance
\section loansreference Reference
\subsection loanssoftware Other software:
Gnumeric supports the following functions WRT payment calculation:
- PMT( rate, nper, pv [, fv, type] )
PMT returns the amount of payment for a loan based on a constant interest
rate and constant payments (ea. payment equal).
@rate : constant interest rate
@nper : overall number of payments
@pv : present value
@fv : future value
@type : payment type
- 0 : end of period
- 1 : beginning of period
- IPMT( rate, per, nper, pv, fv, type )
IPMT calculates the amount of a payment of an annuity going towards
interest. Formula for IPMT is:
IPMT(per) = - principal(per-1) * interest_rate
where:
principal(per-1) = amount of the remaining principal from last period.
- ISPMT( rate, per, nper, pv )
ISPMT returns the interest paid on a given period.
If @per < 1 or @per > @nper, returns #NUM! err.
- PPMT(rate, per, nper, pv [, fv, type] )
PPMT calculates the amount of a payment of an annuity going towards
principal.
PPMT(per) = PMT - IPMT(per)
where: PMT is payment
- IPMT is interest for period per
- PV( rate, nper, pmt [, fv, type] )
Calculates the present value of an investment
@rate : periodic interest rate
@nper : number of compounding periods
@pmt : payment made each period
@fv : future value
*/

View File

@ -1,522 +0,0 @@
/** \page lotsoverview Lots Architecture & Implementation Overview
Linas Vepstas <linas@linas.org>
Last Revised May 2004
API \ref Lot
One often needs to know that the item 'bought' in one transaction
is the same one as the item 'sold' in a different transaction.
Lots are used to make this association. One Lot holds all of the
splits that involve the same item. A lot is typically formed when
the item is bought, and is closed when the item is sold out.
A lot need not be a single item, it can be a quantity of the same
thing e.g. 500 gallons of paint (sold off a few gallons at a time).
Lots are required to correctly implement invoices, inventory,
depreciation and stock market investment gains.
'Lots' capture a fundamental accounting idea behind AR/AP, billing,
inventory, capital gains, depreciation and the like. The basic idea
is that a set of items is tracked together as a 'lot'; the date of
creation of the lot helps determine when a bill is due, when depreciation
starts, or the tax rate for capital gains on a stock market investment.
\section lotsdefines Definition
In GnuCash, a 'lot' will consist of a set of splits identified with
a unique lot number. Any given split can belong to one lot and one
lot only. All splits in a lot must also belong to the same account.
Lots have a 'balance': the sum of all the splits in the lot. A lot
is 'opened' when the first split is assigned to it. The date of that
split is the 'opening date' of the lot, and its quantity is the
'opening balance'. A lot is 'closed' when its balance is zero;
once closed, a lot cannot be re-opened. Open lots are always carried
forward into the current open book; closed lots are left behind in the
book in which they were closed.
\section How Lots Are Used
The following sections review how lots are used to implement various
accounting devices, and some of the related issues.
\subsection Billing
Tracking lots is the 'definition' of A/R and A/P. You want to be able
to say that this bill is 120 days old, and its balance has been partly
paid off; and you want to be able to do this whether or not there are
also other bills, of different ages, to the same company. In GnuCash,
a 'bill' is tracked as a lot: The 'billing date' is the opening date
of the lot, and the 'balance due' is the balance of the lot. When the
bill is 'paid in full', the lot is closed. The average age of
receivables can be computed by traversing all lots, etc. Additional
information about bills, such as a due date or payment terms, should
be stored as kvp values associated with the lot.
\subsection Billing Example
Normally, there is a one-to-one correspondence between bills and
lots: there is one lot per bill, and one bill per lot. (Note: this
is not how gnucash invoices are currently implemented; this is a
proposed implementation.)
For example:
\verbatim
invoice #258 customer XXX
Order placed 20 December 2001
quant (10) gallons paint $10/each $100
quant (2) paintbrushes $15/each $30
sales tax $8.27
------------
Total due $138.27
Payment received 24 january 2002 $50 Balance Due: $88.27
Payment received 13 february 2002 $60 Balance Due: $28.27
Payment received 18 march 2002 $28.27 PAID IN FULL
\endverbatim
In this example, the lot encompasses four transactions, dated
December, January, February and March. The December transaction
opens the lot, and gives it a non-zero balance. To be precise,
the lot actually consists of four splits, belonging to four
different transactions. All four splits are a part of an imagined
"Accounts Receivable-Billing" account. The first split is for
$138.27, the second split is for $50, the third split is for $60,
and the fourth split is for $28.27. Note that the sales-tax
split, and th paint/paint-brush splits are *NOT* a part of this
lot. They are only a part of the transaction that opened this lot.
Note also that this example might also encompass two other lots:
the transfer of paint may belong to a lot in the "Paint Inventory"
account, and the split describing the paintbrushes might be a part
of a lot in the "Paintbrush Inventory" account. These lots should
not be confused with the invoice lot.
\subsection lotsinventory Inventory
The correct way of handling inventory under GnuCash is to have a
separate account for each widget type. The account balance represents
how many widgets there are in the warehouse. Lots offer an additional
level of detail that can be useful when, for example, the widgets have
an expiration date (e.g. milk) or vary slightly from batch to batch
(e.g paint), and creating a new account to track these differences
would be too heavy-weight.
In order to track widgets as single units (and prohibit fractional
widgets), set the currency denominator to 1. This will prevent
fractional widgets from being transferred into/out of an account.
Note that using accounts to track the inventory of a grocery store
causes an explosion of accounts, and this explosion would overwhelm
many of the account GUI's in GnuCash. The GUI should probably be
modified to treat inventory accounts in a special way, e.g. by
not listing them in account lists, and providing an alternate
management GUI.
\subsection Capital Gains
In the United States, gains on stock investments are taxed at different
rates depending on how long they were held before being sold. By using
lots with an investment account, it becomes easy to track when any given
share was bought or sold, and thus, the length of time that share was
held.
Note, however, that using lots might cause some confusion for naive
users, since some transactions might be split across different lots.
For example, the user may have conceptually made the following
transactions:
\verbatim
> Date Desc Buy Sell Price Value
> 18/1/01 XCORP 500 $10.00 $5000.00
> 21/3/01 XCORP 500 $12.00 $6000.00
> 14/7/02 XCORP 750 $20.00 $15000.00
\endverbatim
However, the two buy transactions create different lots (because
you can't add to a stock-investment lot after its been created, because
the purchases occurred on different dates). Thus, when the shares are
sold, the sale is split across two lots:
\verbatim
> Date Desc Lot Buy Sell Price Value
> 18/1/01 XCORP 187 500 $10.00 $5000.00
> 21/3/01 XCORP 188 500 $12.00 $6000.00
> 14/7/02 XCORP 187 500 $20.00 $10000.00
> 14/7/02 XCORP 188 250 $20.00 $5000.00
\endverbatim
In the above, lot 187 was closed, and lot 188 has a balance of 250
shares. Note that we used a FIFO accounting method in this example:
the oldest shares were sold first.
Note also, that by using lots in this example, we are able to accurately
compute the gains in this transaction: it is 500*($20-$10) + 250*($20-$12)
= $5000+$2000 = $7000. If we had used LIFO accounting, and sold the
youngest shares first, then the profits would have been 500*($20-$12)
+ 250*($20-$10) = $4000 + 2500 = $6500. Thus, different accounting
methods do affect income, and thus the tax rate.
Note that the two ledgers, the 'without-lots' and the 'with-lots'
ledgers look different, even though the conceptual transactions are
the same. If a naive user was expecting a 'without-lots' ledger,
and is shown a 'with lots' ledger, they may get confused. I don't
know of any simple way of dealing with this. In order to have lots
work (thereby allowing cap gains reports to work correctly), the GnuCash
engine *must* use the 'with-lots' representation of the data. If the
GUI wants to hide the fact that there are lots under the covers, it
must figure out a way of doing this (i.e. re-combining splits) on
its own.
\section lotsclosing Closing of Books
A few words on lots and the closing of books. Without lots, there
is really no way of correctly implementing book closing. That is
because some reports, such as the capital-gains report, need to know
not only the account balance, but also the purchase dates. Lots
provide the natural mechanism for storing this information.
When a book is closed, any open lots must be moved into/kept with
the open book. Since the splits in a lot belong to transactions,
and transactions are 'atomic', this means that the associated
transactions must be moved into the open book as well. A lot
is considered closed when its balance is zero; when a book is closed,
all of the lots that were closed stay with that book. That is,
closed lots are not propagated forward into the currently open book.
Actually, its slightly more subtle than that. Not only must open
lots stay with the open book, but so must all transactions that
have splits that participate in the open lot, and, by extension,
all closed lots that participate in these 'open transactions',
ad infinitum.
\section lotsdouble The "Double Balance" Requirement
The following is a proposal for how to handle both realized
and unrealized gains/losses by means of "adjusting transactions."
It works for simple cases, but has issues for more complex cases.
Canonical transaction balancing: If all splits in a transaction
are in the same 'currency' as the transaction currency, then the
sum of the splits *must* equal zero. This is the old, existing
double-entry requirement as implemented in Gnucash, and doesn't
change.
If some splits are in one commodity, and others in another, then
we can't force a zero balance as above. Instead, we will force
a different requirement, the 'double-balance' requirement:
- All splits that are *not* in the transaction currency C
must be made a part of a lot. (Thus, for example,
the transaction currency C is dollars, whereas the split
commodity is 'S', shares of RHAT. If a transaction
has C in dollars, and 'S' in RHAT, then the S split must
be made a part of a Lot.)
- The lot will have a designated 'lot currency' L that must
be the same as the C of every split in the lot. One
cannot enter a split into the lot if C != L. (That is,
if I'm working with a Lot of RHAT shares, then *all*
splits in the lot must belong to dollar-denominated
transactions.)
- When a lot is closed, we must have the 'double-balance'
condition: The sum total of all 'S' is zero, and the
sum total of all 'C' is zero. Thus, if I buy 100 shares
of RHAT for $5 and sell 100 shares of RHAT for $10, then
I *must* also add an 'adjusting transaction' for zero
shares of RHAT, at $500. If there is no adjusting transaction,
then the lot cannot be closed. If sum 'S' is zero,
while sum 'C' is not zero, then the lot is declared to
be 'out-of-balance', and an 'adjusting transaction' must
be forced.
It is only by 'closing a lot' that one is able to regain
'perfect balance' in the books. That is, the 'double-balance'
requirement is the generalization of the 'double-entry'
requirement for stock accounts.
Note that because the 'adjusting transaction' has one split
in dollars, and another split in RHAT shares (albeit for zero
RHAT shares), it evades the old double-entry requirement,
and will not be flagged as 'out of balance'. Note also
that because the 'adjusting transaction' contains a split
holding S (albeit zero S), it *must* be a part of a Lot.
The above seems to work for simple stock-transactions, but
fails in other more complex cases. Here's an example.
Imagine 'S' is in euros, instead of 'RHAT'. So I sell
100 dollars, and buy 110 euros. This causes a lot to open
up for the euros, with the lot currency 'L' in dollars.
Now I try to transfer the euros to other euro accounts.
What happens to the lot? Do I have to give up on it?
How can I save this bad situation?
A similar problem occurs for more complex stock transactions:
If I buy 100 shares of RHAT with Schwab, and transfer them
to another account with Etrade, then I have the same lot
closing problem. There's an even worse scenario, where
I move to Brazil, and take my RHAT stock (purchased in dollars)
to my Brazilian broker (who will sell them for cruzeiros).
Is the correct answer to just 'punt' in these cases?
How is the closing of books to be handled in such a case?
GUI Elements:
- The user should be able to specify a default 'realized-gain'
account that is associated with a stock account.
- The user should be able to specify a default 'unrealized-gain'
account that is associated with a stock account.
\section lotsfifo FIFO's
What is a FIFO ? A FIFO is a type of accounting policy where
income from selling inventory is accounted by selling the oldest
inventory first. Thus, the profit/loss of the sale corresponds
to the difference in price between when it was bought and sold.
FIFO's are also used in depreciation schedules, and in other places.
Currently the only policy that is implemented in the cap-gains
code is the FIFO policy. I believe that it's been abstracted
properly, so that it should be easy to add other policies,
e.g. LIFO. See policy.c for what would need to be implemented.
\section lotsimplement Implementation
Every split has a pointer to a lot (which may be null). A lot has a list
of splits in it (so that the other splits in the lot can be easily found).
A lot does not need to maintain a balance (this is easy enough to calculate
on the fly). A lot has a kvp tree (for storage of lot-related date, such
as due dates for invoices, etc. A lot has a GUID.
From the memory-management and data-base management point of view, lots
belong to accounts. The GnuCash account structure maintains a list of
lots so that all lots belonging to an account can be quickly retrieved.
(In principle, the lots can be found by scanning every split in the
account, but this is a painful process.)
\section lotscapgains Implementing Cap Gains (Is a Pain in the Neck)
Although Lots provide a good conceptual framework for determining
gains or losses when a lot is closed, cap-gains on half-open
lots present additional complexities. Consider the following
stock purchase and subsequent sale of half the stock:
Account A is a stock account
Account B is a bank account
Account C is an income account
\verbatim
Acct A Txn Acct B Acct C
Date Action Amt Prc Value Amt Amt
1/1/01 buy 100s $10 $1000 ($1000) -
2/2/02 sell (50)s $25 $1250 $1250 -
2/2/02 gain - - $750 $750
\endverbatim
The gain, shown in the third line, is computed as a straight
sum of purchase price to sale price.
Should the above be represented as two transactions, or as three?
One could, in principle, combine the second and third lines into
one transaction. However, this has some drawbacks: computing
the overall balance of such a transaction is tricky, because
it has so many different splits (including, possibly, splits
for brokerage fees, tax, etc. not shown). The alternative
is to represent each line as a separate transaction. This has
other drawbacks: If the date, amount, price or value is adjusted
for the second transaction, the corresponding values must be
adjusted for the third, and vice-versa.
Both schemes pose trouble for the register display: we want
the stock register to show the gain as if it were a part of
the stock sale; but the third line is a pair of splits, and
we want to show only one of these two splits. Whichever method
is chosen, the register has to filter out some of the splits
that it shows.
The implementation that seems best is to represent the sale
with two separate transactions: one for the sale itself, and a
separate one for the gains. This makes computing the balance
easier, although it makes the logic for setting the date
more complex. Ughh..
\section loanscapnotes Cap Gains Implementation Notes
Cap Gains will be handled by GnuCash as described above, using
two distinct transactions. These transactions will be marked up
using KVP, pointing to each other, so that the one can be found
from the other. Implementation in src/engine/cap-gains.c
Quick API Overview:
- xaccSplitGetCapGains(): Returns the capital gains associated with
a split. Split must have been a sale/purchase in a previously
opened lot.
- xaccSplitAssignToLot(): If a split is not already in a lot,
then it places it into a lot, using a FIFO accounting policy.
\section lotscapimplement Cap Gains Actual Implementation
Cap Gains are noted by creating a separate transaction with two
splits in it. One of the splits is as described above: zero
amount, non-zero value. There is a GUI requirement that when
the looking at a gains transaction, certain things need to be
kept in sync with the transaction that is the source of the gains.
In order to accomplish this, the engine uses a set of 'dirty'
flags, and a pair of pointers between the gains split and the
source split, so that the one can be quickly found from the other.
Things kept in sync:
- date posted
- value
- void status
- other things ?
Things not kept in sync:
- kvp trees
- description, memo, action.
The posted date is kept in sync using a data-constraint scheme.
If xaccTransactionSetDatePosted() is called, the date change is
accepted, and the split is marked date-dirty. When the transaction
is committed (using xaccTransCommitEdit()), the date-dirty flag
is evaluated, and, if needed, the date changes are propagated/rolled
back on the appropriate gains splits. Currently, one can only change
the date on the gains-source transaction; the date on the
gains-recording split cannot be changed.
The value recorded by the gains transaction is updated whenever
the value of the source changes. The actual update is done by
the xaccSplitComputeCapGains() routine, via xaccScrubLot(), which
is called at the time of xaccTransCommitEdit(). Note that two
different things can affect the gains: a change in the value of
the sale, and a change of the value of the purchase. A set of
dirty flags are used to track these.
If the amount of a plit changes, then the lot that its in becomes
potentially unbalanced. This requires the lot membership to be
recomputed; this in turn may require the split to be split into
pieces, or to be recombined into one from several pieces.
\section lotstodo TODO
- need to copy void status when source split date changes.
- its possible for the the price, as recorded by one split
to vary wildly from that in another split in the same
transaction. That's bad, prices should be normalized.
There's a routine to do this, xaccScrubSubSplitPrice()
but its not currently used.
- write automated test cases to handle each situation.
\section lotsconversion Conversion
As Lots are put into production, old GnuCash datasets
will need to be converted. Conversion will be done by running
all splits in an account through an accounting policy (currently,
there is only one policy, a FIFO). The goal of the policy is to
match up purchases and sales so that these can be assigned to a Lot.
The conversion algorithm will work as follows:
\verbatim
for each account {
loop over splits {
// perform the 'double-balance' check
if (split commodity != transaction currency) account needs conversion
}
if account needs conversion
for each split {
If (split amount > 0) create new lot, put split in lot.
If (split amount < 0) find oldest lot, put split in that lot
}
}
\endverbatim
See the file Scrub2.h for details of the low-level API, and Scrub3.h
for the high-level API.
There is a bit of a problem with this conversion procedure: If the
user had previously recorded cap gains using a 'handmade' version of
lots, those cap gains will be ignored and will throw off balances.
User will need to hand-edit to recover.
- TODO: Modify scrub routines to look for splits with zero amount,
try to assign these to lots as appropriate. ??
\section lotsgui GUI
A GUI for handling Lots is needed: ability to view a lot, and to cut/paste
or move a split from one lot to another. Need a GUI to create a lot,
maybe append some notes to it. Need ability to view account in lot-mode.
For automatically managing accounts, need to implement a variety of
different accounting policies (of which the FIFO policy is currently
implemented in the 'Scrub' routines).
\subsection lotsbasicgui Basic GUI
The goal of the basic GUI is to handle most usages of
most lots in most places. There also need to be special-purpose
dialogs for specific applications, e.g. stocks, inventory, etc.
Shows three areas:
- list of lots, one of which can be highlighted.
Lot names can be edited in-place.
- contents of a single lot (displayed in a narrow,
mini-register view, showing only date, memo, quant,
balance)
- list of splits not in any lot.
(not clear if screen real-estate allows side-by-side
placement, or if this must be above/below. above/below
would suck)
Shows various buttons:
- two arrows, which move split into/out of lot.
This is a traditional way of moving something from one
list to another, but some UI designers argue against this.
Is there a better way to move splits into/out-of a lot?
- button, labeled 'close lot', which, when pressed, will
set lot balance to zero. (by using fifo on the unassigned
splits, if possible).
- A field showing realized gain/loss on a closed lot, and
a pull-down allowing the gain/loss to be posted to a
specific account.
(The default is stored in kvp:/lots-mgmt/gains-acct/)
- button or menu item, 'add notes to this lot'.
\subsection lotsguitodo todo:
- change lot viewer to use gnc-query-list
- after the gnome2 port, add the 'unclaimed splits" window
to the lot viewer, this will allow it to be a simple lot editor.
- Add a new policy (or change the existing fifo policy) to only
open lots with a particular sign for the opening split. This
way, things like business invoice overpayments are not used
to start new lots, but are instead applied to new purchases.
\section lotsstatus Status
- Core support for Lots in the engine is complete (April 2002, ships in
version 1.8.x, used by business backend).
- See src/engine/gnc-lot.h for the public API.
- The XML backend support for lot is complete (April 2002, ships in
version 1.8.x).
- Scrub routines to automatically take old gnucash datasets and
transition them to double-balanced lots have been implemented.
These implement a FIFO accounting policy (April 2003)
- Closed/Open lots are handled correctly during book closing.
See src/engine/Period.c (August 2003)
- Work is finished on the automatic computation & tracking
of gain/loss transactions. Most of the engine API is in
src/engine/cap-gains.h although the high-level 'scrub' API
is in src/engine/Scrub3.h. See src/doc/constraints.txt for
a 'big picture' view of how its done. (September 2003)
- A basic lot-viewing GUI is in src/gnome/lot-viewer.c
This GUI cannot 'edit' lots. (August 2003)
- Need to write extensive test cases to verify the rather complex
constraints between the gains and lots and splits.
- Need to write a cap-gains report!
*/
-------------------------- end of file ------------------------------

View File

@ -1,135 +0,0 @@
## @file
# @brief Documentation file for GnuCashs python bindings, input file for doxygen.
#
# This file holds the more explanatory parts of the doxygen-source-documentation.
# You will find the contents at @ref python_bindings_page.
#
# @par To-Do:
# @li Work out the relation of scheme/guile and python-bindings
# @li maybe join python_bindings_page and group
# @li work on the structure of the documentation to make it more clear
# @li try to make SWIG include the documentation of the c-source
# @li make function-links in SWIG-generated files work.
# @li some words to the tests
#
# @author Christoph Holtermann
# @date December 2010
# @ingroup python_bindings
## @defgroup python_bindings Python Bindings Module
# Also have a look at the page @ref python_bindings_page.
## @defgroup python_bindings_examples Python Bindings Examples Module
# @ingroup python_bindings
# The python-bindings come with quite a lot of example scripts.
## @page python_bindings_page Python bindings
# Also have a look at group @ref python_bindings.
#
# In the source tree they are located at bindings/python.
#
# To enable them in the compilation process you have to add -DWITH_PYTHON=ON
# to the call of cmake.
#
# As a starting point have a look at the \link python_bindings_examples example-scripts\endlink.
#
# @section possibilities What can Python Bindings be used for ?
#
# The python bindings supply the ability to access a wide range of the core functions of GnuCash. You
# can read and write Transactions, Commodities, Lots, access the business stuff... You gain the ability
# to manipulate your financial data with a flexible scripting language.
#
# Not everything GnuCash can is possible to access though. The bindings focus on basic accounting functions.
# Have a look at the examples to get an impression.
#
# Some functions are broken because they have not been wrapped properly. They may crash the program or return unaccessible values.
# Please file a bug report if you find one to help support the development process.
#
# @section python_bindings_section Principles
# The python-bindings are generated using SWIG from parts of the source-files of GnuCash.
#
# @note Python-scripts should not be executed while GnuCash runs. GnuCash is designed as
# a single user application with only one program accessing the data at one time. You can force your
# access but that may corrupt data. Maybe one day that may change but for the moment there is no active development on that.
#
# @subsection swigworks What SWIG does
#
# SWIG extracts information from the c-sources and provides access to the structures
# to python. It's work is controlled by interface files :
#
# @li gnucash_core.i
# @li timespec.i
# @li glib.i
# @li @link base-typemaps.i src/base-typemaps.i @endlink This file is shared with Guile.
#
# it outputs:
#
# @li gnucash_core.c
# @li gnucash_core_c.py
#
# If you have generated your own local doxygen documentation (by "make doc") after having compiled the python-bindings, doxygen
# will include SWIGs output-files.
# It's actually quite interesting to have a look at them through doxygen, because they contain all that you can
# access from python.
#
# This c-style-api is the bottom layer. It is a quite raw extract and close to the original source. Some more details are described further down.
#
# For some parts there is a second layer of a nice pythonic interface. It is declared
# in
# @li gnucash_core.py and
# @li gnucash_business.py.
# @li function_class.py contains helper functions for that.
#
# @section howto How to use the Python bindings
# @subsection highlevel High level python wrapper classes
# If you
#
# @code >> import gnucash @endcode
#
# You can access the structures of the high level api. For Example you get a Session object by
#
# @code >> session=gnucash.Session() @endcode
#
# Here you will find easy to use things. But sometimes - and at the current level rather sooner than
# later - you may be forced to search for solutions at the :
#
# @subsection c_style_api C-style-api
#
# If you
#
# @code >> import gnucash @endcode
#
# The c-style-api can be accessed via gnucash.gnucash_core_c. You can have a look at all the possibilities
# at gnucash_core_c.py.
#
# You will find a lot of pointers here which you can just ignore if input and output of the function have the
# same type.
#
# For example you could start a session by gnucash.gnucash_core_c.qof_session_begin(). But if you just try
#
# @code session=gnucash.gnucash_core_c.qof_session_begin() @endcode
#
# you will get an error message and realize the lack of convenience for you have to add the correct function parameters.
#
# Not all of the available structures will work. SWIG just takes everything from the sources that it is fed with and translates it. Not everything
# is a working translation, because not everything has been worked through. At this point you are getting closer to the developers who you can
# contact at the mailing-list gnucash-devel@gnucash.org. There may be a workaround. Maybe the problem can only be fixed by changing SWIGs input
# files to correctly translate the c-source. Feel free to post a question at the developers list. It may awaken the interest of someone who creates
# some more beautiful python-interfaces.
#
# @section Thisorthat When to use which api ?
#
# The start would surely be the high-level api for you can be quite sure to have something working and you will maybe find
# explanations in the example-scripts. If you search for something that is not yet implemented in that way you will have to
# take your way to the c-style-api.
#
# @section pydoc (Further) documentation
#
# @li The documentation you just read uses doxygen. It collects documentation in GnuCash's sources. Besides that there is
# @li the classic python-documentation using help() and docstrings. Have a look at both.
# @li There is a page in the GnuCash wiki at https://wiki.gnucash.org/wiki/Python
# @li You may also have a look into the archives of gnucash-devel@gnucash.org.
# @li On Bugzilla there is also some interesting talk regarding the development process.
# @li Then you can use the abilities of git to see the history of the code by @code git log @endcode done in the directory of the python-bindings.
#

View File

@ -282,7 +282,6 @@ set(engine_EXTRA_DIST
README
README.query-api
SX-book-p.h
TaxTableBillTermImmutability.txt
)
if (NOT WIN32)

View File

@ -335,3 +335,293 @@ gboolean SXRegister (void);
/** @} */
/** @} */
/** \page loanhandling Handling loan repayment in GnuCash::Scheduled Transactions
* \sa The original email thread at <https://lists.gnucash.org/pipermail/gnucash-devel/2002-July/006438.html>.
*
* July, 2002 - jsled@asynchronous.org
*
* API: \ref SchedXaction
*
* We define loan repayment values in the following terms:
*
* Identifiers:\n
* P : the original principal. This is the overall principal afforded by the
* loan at the time of it's creation.\n
* P' : The beginning principal. This is the principal at the time of entry
* into GnuCash.\n
* I : The interest rate associated with the loan. Note that this may change
* over time [based on an addition to the Prime rate, for instance], at
* various frequencies [yearly, monthly, quarterly...]. Ideally, we can
* use the FreqSpec mechanism to facilitate the interest rate adjustment.\n
* N : The length of the loan in periods.\n
* m : The minimum periodic payment.\n
* n : The current period of the repayment.
*
* Functions:\n
* PMT : Total equal periodic payment, as per Gnumeric/Excel's definitions
* [see end for more detail].\n
* IPMT : Monthly payment interest portion, ""\n
* PPMT : Monthly payment principal portion, ""
*
* [ NOTE: 'PMT(I,N,P) = IPMT(I, n, N, P) + PPMT(I, n, N, P)' for 0 <= n < N ]
*
*
* The formula entered into the SX template for a loan may then look like:
*
* Example 1:
* \verbatim
* Desc/Memo | Account | Credit | Debit
* ----------+-----------------------------+----------------+-------------------
* Repayment | Assets:Bank:Checking | | =PMT(I,n,N,P)
* | | | + fixed_amt
* Interest | Expenses:Loan_Name:Interest | =IPMT(I,n,N,P) |
* PMI | Expenses:Loan_Name:Misc | fixed_amt |
* Principal | Liabilities:Loan_Name | =PPMT(I,n,N,P) |
* -----------------------------------------------------------------------------
* \endverbatim
*
* Or, in the case where an escrow account is involved [with thanks to warlord
* for the review and fixes]:
*
* Example 2:
* \verbatim
* Desc/Memo | Account | Credit | Debit
* ---------------+-----------------------------+----------------+--------------
* Repayment | Assets:Bank:Checking | | =PMT(I,n,N,P)
* | | | + escrow_amt
* | | | + fixed_amt
* | | | + pre_payment
* Escrow | Assets:Loan_Escrow_acct | escrow_amt |
* Interest | Expenses:Loan_Name:Interest | =IPMT(I,n,N,P) |
* PMI | Expenses:Loan_Name:Misc | fixed_amt |
* Principal | Liabilities:Loan_Name | =PPMT(I,n,N,P) |
* | | + pre_payment |
* \endverbatim
*
* FreqSpec = 1 month
* \verbatim
* -----------------------------------------------------------------------------
*
* Desc/Memo | Account | Credit | Debit
* ---------------+-----------------------------+----------------+--------------
* Insurance | Assets:Loan_Escrow_acct | | insurance_amt
* Insurance | Expenses:Home_Insurance | insurance_amt |
* \endverbatim
*
* FreqSpec = 1 year
* \verbatim
* -----------------------------------------------------------------------------
* Desc/Memo | Account | Credit | Debit
* ---------------+-----------------------------+----------------+--------------
* Taxes | Assets:Loan_Escrow_acct | | taxes_amt
* Taxes | Expenses:Property_Taxes | taxes_amt |
* FreqSpec = Quarterly
* -----------------------------------------------------------------------------
* \endverbatim
*
*
* \section guidpractical Practical questions regarding the implementation of this facility are:
*
* | 1. The transactions as in Example 2 are not going to be scheduled for the\n
* | same day; are their values linked at all / do they need to share the\n
* | same var bindings?
*
* Yes, they would want to be linked. More precisely, the insurance/tax amounts
* are very likely linked to the escrow_amt in Ex.2. Unfortunately, these are
* very likely separate SXes...
*
* -----
* | 2. How does this effect the SX implementation of variables?
*
* Vastly.
*
* It becomes clear that multiple SXes will be related. While they'll have
* separate FreqSpecs and template transactions, they'll share some state. For
* both visualization [i.e., the SX list] and processing [credit/debit cell
* value computation] we'll want some manner of dealing with this.
*
* It becomes clear as well that the nature of variables and functions needs to
* be more clearly defined with respect to these issues. We probably want to
* institute a clear policy for the scoping of variables. As well, since the
* SXes will have different instantiation dates, we'll need a method and
* implementation for the relation of SXes to each other.
*
* A substantial hurdle is that if a set of SXes are [strongly] related, there
* is no-longer a single instantiation date for a set of related SXes. In fact,
* there may be different frequencies of recurrence.
*
* One option -- on the surface -- to relate them would be to maintain an
* instance variable-binding frame cache, which would store user-entered and
* computed variable bindings. The first instantiated SX of the set would create
* the frame, and the "last" instance would clean it up. First "last" instance
* is defined by the last-occurring SX in a related set, in a given time range.
*
* For example: a loan SX-set is defined by two monthly SXes ["repayment" and
* "insurance"], and a quarterly "tax" SX. The first monthly SX would create a
* frame, which would be passed two the second monthly SX. This would occur for
* the 3 months of interest. The Quarterly SX would get all 3 frames for it's
* creation, and use them in an /appropriate/ [read: to be defined through a lot
* of pain] way. As the time-based dependency relationship between the frames
* plays out, the frame can be removed from the system.
*
* Another option is to toss this idea entirely and instead let the user DTRT
* manually.
*
* A related option is to add the necessary grouping mechanism to the SX
* storage/data structure: immediately allowing visual grouping of related SXes,
* and potentially allowing a storage place for such frame data in the future
* with less file-versioning headache. This is the option that will be pursued.
*
* Another element implicit in the original requirements to support
* loans/repayment calculations is implicit variables. These are symbolic names
* which can be used and are automagically bound to values. The known implicit
* variables to support loan/repayment are:
*
* P [loan principal amount], N [loan repayment periods], I [interest], m
* [minimum payment] and n [current period]. Some of these [P, N, I, m] are
* fixed over many instances; some [n] are rebound specific to the instance.
* See the 'variable-scope-frame' below for a method of handling these
* variables.
*
* And yet-another element implicit in the original requirement is support for
* detecting and computing the result of functions in the template transaction's
* credit/debit cells. Changes to the src/app-utils/gnc-exp-parser.[hc] and
* src/calculation/expression_parser.[ch] to support functions would be
* necessitated. It is conceivable that after parsing, the parsed expression
* could be passed to scheme for evaluation. Hopefully this would make it
* easier to add support for new functions to the SX code via Scheme.
*
*
* | 3. How do we deal with periodic [yearly, semi-yearly] updating of various\n
* | "fixed" variables?
*
* Another change in the way variables are used is that some SXes -- especially
* loan-repayment -- may involve variables which are not tied to the instance of
* the SX, but rather to variables which:
* - are also involved in another SX
* - change with a frequency different than the SX
* - are represented by a relationship to the outside world ["prime + 1.7"]
*
* A partial fix for this problem is to provide multiple levels of scope for
* variable bindings, and expose this to the user by a method of assigning
* [perhaps time-dependent] values to these variables. Variables bound in this
* manner would absolve the user of the need to bind them at SX-creation time.
*
* An added benefit of this would be to allow some users [see Bug#85707] have
* "fixed variable" values for a group of SXes.
*
* In combination with the SX Grouping, this would provide most of a fix for the
* problem described in #2, above. The variable_frame could be used to provide
* the shared-state between related SXes, without imposing quite the same
* burden. This approach is slightly less flexible, but that allows it to be
* implemented more readily, and understood more easily.
*
* A question which comes up when thinking about yearly-changing values such as
* interest rates is if the historical information needs to be versioned. For
* now, we punt on this issue, but hopefully will provide enough of a framework
* for this to be reasonably added in the future.
*
* We define four types of variables supported by this scheme:
*
* implicit : provided only by the system
* e.g.: 'n', the current index of the repayment
*
* transient : have user-defined values, bound at instantiation time.
* e.g.: existing ad-hoc variables in SXes.
*
* static : have a user-defined values, and are not expected to change with
* any measurable frequency. The user may change these at their
* leisure, but no facility to assist or encourage this is
* provided.
* e.g.: paycheck amount, loan principal amount
*
* periodic : have user-defined values which change at specific points in
* time [July 1, yearly]. After the expiration of a variable value,
* it's re-binding will prevent any dependent SXes from being
* created.
* e.g.: loan tax amount, loan interest rate
*
* | 4. From where do we get the dollar amount against which to do the [PI]PMT\n
* | calculation?
*
* The user will specify the parameters of the Loan via some UI... then where
* does the data go?
*
* - KVP data for that account?
* - KVP data for the SX?
* - Do we have a different top-level "Loan" object?
* - Present only in the SX template transactions/variable-frames?
*
* I believe that the only location of the data after Druid creation is in the
* variable-binding frames and the formulae in the template transactions. The
* Druid would thus simply assist the user in creating the following SX-related
* structures:
*
* - SXGroup: Loan Repayment
* - variable_frame
* - P [static]
* - N [static]
* - n [implicit]
* - I [periodic]
* - pmi_amount [periodic]
* - tax_amount [periodic]
* - pre_payment [periodic]
* - insurance_amount [periodic]
* - SX: Payment
* - Bank -> { Escrow,
* Liability:Loan:Principal,
* Expense:Loan:Interest,
* Expense:Loan:Insurance }
* - SX: Tax
* - Escrow -> Expense:Tax
* - SX: Insurance
* - Escrow -> Expense:Insurance
*
*
* \section loansreference Reference
*
*
* \subsection loanssoftware Other software:
*
* Gnumeric supports the following functions WRT payment calculation:
*
* - PMT( rate, nper, pv [, fv, type] )
* PMT returns the amount of payment for a loan based on a constant interest
* rate and constant payments (ea. payment equal).
* @rate : constant interest rate
* @nper : overall number of payments
* @pv : present value
* @fv : future value
* @type : payment type
* - 0 : end of period
* - 1 : beginning of period
*
* - IPMT( rate, per, nper, pv, fv, type )
* IPMT calculates the amount of a payment of an annuity going towards
* interest. Formula for IPMT is:
* IPMT(per) = - principal(per-1) * interest_rate
* where:
* principal(per-1) = amount of the remaining principal from last period.
*
* - ISPMT( rate, per, nper, pv )
* ISPMT returns the interest paid on a given period.
* If @per < 1 or @per > @nper, returns #NUM! err.
*
* - PPMT(rate, per, nper, pv [, fv, type] )
* PPMT calculates the amount of a payment of an annuity going towards
* principal.
* PPMT(per) = PMT - IPMT(per)
* where: PMT is payment
* - IPMT is interest for period per
*
* - PV( rate, nper, pmt [, fv, type] )
* Calculates the present value of an investment
* @rate : periodic interest rate
* @nper : number of compounding periods
* @pmt : payment made each period
* @fv : future value
*
*
*/

View File

@ -1,41 +0,0 @@
/**
\addtogroup Business
@{
\addtogroup ImmutableTaxTableBillTerm TaxTable and BillTerm immutability tracking
Derek Atkins <warlord@mit.edu>
Version of October 2003
The gncTaxTable and gncBillTerm business objects have parent, child,
refcount, invisible field in their structures that deserve some
explanation:
- a child is a 'frozen' instance of a parent. For example, the tax
percentage in a particular tax table may change over time, but you
dont want that change to affect already-posted invoices... So you
make sure there is an immutable 'copy' (read: child) of the tax
table when you post the invoice and repoint at the child.
- a parent can have many children, but it will only have a 'child'
pointer if the parent has not been modified. Think of this as a
copy-on-write mechanism. posted invoices will continue to use the
_same_ child until the parent is modified, at which point a new
child will be created.
- invisible means "dont show this in the list". It's so you dont
get all the children in the tax table list -- you only see parents.
I suppose this flag could also be called "is-child" as I believe that
only children can be invisible, and ALL children are invisible.
- refcount is a listing of how many objects are referencing it.
Basically, it's letting you know how many customer, vendor, entries,
etc are referencing e.g. a particular tax table object. mostly this
was done to make sure you cannot delete an in-use taxtable.
- children don't use refcounts, only parents do.
- A child always points to its parent (it can have only 1).
- A parent has a list of all children.
- A parent has a pointer to the current 'replica child', if one exists.
*/

View File

@ -194,3 +194,438 @@ GNCLot * gnc_lot_make_default (Account * acc);
#endif /* GNC_LOT_H */
/** @} */
/** @} */
/** \page lotsoverview Lots Architecture & Implementation Overview
Linas Vepstas <linas@linas.org>
Last Revised May 2004
API \ref Lot
One often needs to know that the item 'bought' in one transaction
is the same one as the item 'sold' in a different transaction.
Lots are used to make this association. One Lot holds all of the
splits that involve the same item. A lot is typically formed when
the item is bought, and is closed when the item is sold out.
A lot need not be a single item, it can be a quantity of the same
thing e.g. 500 gallons of paint (sold off a few gallons at a time).
Lots are required to correctly implement invoices, inventory,
depreciation and stock market investment gains.
'Lots' capture a fundamental accounting idea behind AR/AP, billing,
inventory, capital gains, depreciation and the like. The basic idea
is that a set of items is tracked together as a 'lot'; the date of
creation of the lot helps determine when a bill is due, when depreciation
starts, or the tax rate for capital gains on a stock market investment.
\section lotsdefines Definition
In GnuCash, a 'lot' will consist of a set of splits identified with
a unique lot number. Any given split can belong to one lot and one
lot only. All splits in a lot must also belong to the same account.
Lots have a 'balance': the sum of all the splits in the lot. A lot
is 'opened' when the first split is assigned to it. The date of that
split is the 'opening date' of the lot, and its quantity is the
'opening balance'. A lot is 'closed' when its balance is zero;
once closed, a lot cannot be re-opened. Open lots are always carried
forward into the current open book; closed lots are left behind in the
book in which they were closed.
\section How Lots Are Used
The following sections review how lots are used to implement various
accounting devices, and some of the related issues.
\subsection Billing
Tracking lots is the 'definition' of A/R and A/P. You want to be able
to say that this bill is 120 days old, and its balance has been partly
paid off; and you want to be able to do this whether or not there are
also other bills, of different ages, to the same company. In GnuCash,
a 'bill' is tracked as a lot: The 'billing date' is the opening date
of the lot, and the 'balance due' is the balance of the lot. When the
bill is 'paid in full', the lot is closed. The average age of
receivables can be computed by traversing all lots, etc. Additional
information about bills, such as a due date or payment terms, should
be stored as kvp values associated with the lot.
\subsection Billing Example
Normally, there is a one-to-one correspondence between bills and
lots: there is one lot per bill, and one bill per lot. (Note: this
is not how gnucash invoices are currently implemented; this is a
proposed implementation.)
For example:
\verbatim
invoice #258 customer XXX
Order placed 20 December 2001
quant (10) gallons paint $10/each $100
quant (2) paintbrushes $15/each $30
sales tax $8.27
------------
Total due $138.27
Payment received 24 january 2002 $50 Balance Due: $88.27
Payment received 13 february 2002 $60 Balance Due: $28.27
Payment received 18 march 2002 $28.27 PAID IN FULL
\endverbatim
In this example, the lot encompasses four transactions, dated
December, January, February and March. The December transaction
opens the lot, and gives it a non-zero balance. To be precise,
the lot actually consists of four splits, belonging to four
different transactions. All four splits are a part of an imagined
"Accounts Receivable-Billing" account. The first split is for
$138.27, the second split is for $50, the third split is for $60,
and the fourth split is for $28.27. Note that the sales-tax
split, and th paint/paint-brush splits are *NOT* a part of this
lot. They are only a part of the transaction that opened this lot.
Note also that this example might also encompass two other lots:
the transfer of paint may belong to a lot in the "Paint Inventory"
account, and the split describing the paintbrushes might be a part
of a lot in the "Paintbrush Inventory" account. These lots should
not be confused with the invoice lot.
\subsection lotsinventory Inventory
The correct way of handling inventory under GnuCash is to have a
separate account for each widget type. The account balance represents
how many widgets there are in the warehouse. Lots offer an additional
level of detail that can be useful when, for example, the widgets have
an expiration date (e.g. milk) or vary slightly from batch to batch
(e.g paint), and creating a new account to track these differences
would be too heavy-weight.
In order to track widgets as single units (and prohibit fractional
widgets), set the currency denominator to 1. This will prevent
fractional widgets from being transferred into/out of an account.
Note that using accounts to track the inventory of a grocery store
causes an explosion of accounts, and this explosion would overwhelm
many of the account GUI's in GnuCash. The GUI should probably be
modified to treat inventory accounts in a special way, e.g. by
not listing them in account lists, and providing an alternate
management GUI.
\subsection Capital Gains
In the United States, gains on stock investments are taxed at different
rates depending on how long they were held before being sold. By using
lots with an investment account, it becomes easy to track when any given
share was bought or sold, and thus, the length of time that share was
held.
Note, however, that using lots might cause some confusion for naive
users, since some transactions might be split across different lots.
For example, the user may have conceptually made the following
transactions:
\verbatim
> Date Desc Buy Sell Price Value
> 18/1/01 XCORP 500 $10.00 $5000.00
> 21/3/01 XCORP 500 $12.00 $6000.00
> 14/7/02 XCORP 750 $20.00 $15000.00
\endverbatim
However, the two buy transactions create different lots (because
you can't add to a stock-investment lot after its been created, because
the purchases occurred on different dates). Thus, when the shares are
sold, the sale is split across two lots:
\verbatim
> Date Desc Lot Buy Sell Price Value
> 18/1/01 XCORP 187 500 $10.00 $5000.00
> 21/3/01 XCORP 188 500 $12.00 $6000.00
> 14/7/02 XCORP 187 500 $20.00 $10000.00
> 14/7/02 XCORP 188 250 $20.00 $5000.00
\endverbatim
In the above, lot 187 was closed, and lot 188 has a balance of 250
shares. Note that we used a FIFO accounting method in this example:
the oldest shares were sold first.
Note also, that by using lots in this example, we are able to accurately
compute the gains in this transaction: it is 500*($20-$10) + 250*($20-$12)
= $5000+$2000 = $7000. If we had used LIFO accounting, and sold the
youngest shares first, then the profits would have been 500*($20-$12)
+ 250*($20-$10) = $4000 + 2500 = $6500. Thus, different accounting
methods do affect income, and thus the tax rate.
Note that the two ledgers, the 'without-lots' and the 'with-lots'
ledgers look different, even though the conceptual transactions are
the same. If a naive user was expecting a 'without-lots' ledger,
and is shown a 'with lots' ledger, they may get confused. I don't
know of any simple way of dealing with this. In order to have lots
work (thereby allowing cap gains reports to work correctly), the GnuCash
engine *must* use the 'with-lots' representation of the data. If the
GUI wants to hide the fact that there are lots under the covers, it
must figure out a way of doing this (i.e. re-combining splits) on
its own.
\section lotsclosing Closing of Books
A few words on lots and the closing of books. Without lots, there
is really no way of correctly implementing book closing. That is
because some reports, such as the capital-gains report, need to know
not only the account balance, but also the purchase dates. Lots
provide the natural mechanism for storing this information.
When a book is closed, any open lots must be moved into/kept with
the open book. Since the splits in a lot belong to transactions,
and transactions are 'atomic', this means that the associated
transactions must be moved into the open book as well. A lot
is considered closed when its balance is zero; when a book is closed,
all of the lots that were closed stay with that book. That is,
closed lots are not propagated forward into the currently open book.
Actually, its slightly more subtle than that. Not only must open
lots stay with the open book, but so must all transactions that
have splits that participate in the open lot, and, by extension,
all closed lots that participate in these 'open transactions',
ad infinitum.
\section lotsdouble The "Double Balance" Requirement
The following is a proposal for how to handle both realized
and unrealized gains/losses by means of "adjusting transactions."
It works for simple cases, but has issues for more complex cases.
Canonical transaction balancing: If all splits in a transaction
are in the same 'currency' as the transaction currency, then the
sum of the splits *must* equal zero. This is the old, existing
double-entry requirement as implemented in Gnucash, and doesn't
change.
If some splits are in one commodity, and others in another, then
we can't force a zero balance as above. Instead, we will force
a different requirement, the 'double-balance' requirement:
- All splits that are *not* in the transaction currency C
must be made a part of a lot. (Thus, for example,
the transaction currency C is dollars, whereas the split
commodity is 'S', shares of RHAT. If a transaction
has C in dollars, and 'S' in RHAT, then the S split must
be made a part of a Lot.)
- The lot will have a designated 'lot currency' L that must
be the same as the C of every split in the lot. One
cannot enter a split into the lot if C != L. (That is,
if I'm working with a Lot of RHAT shares, then *all*
splits in the lot must belong to dollar-denominated
transactions.)
- When a lot is closed, we must have the 'double-balance'
condition: The sum total of all 'S' is zero, and the
sum total of all 'C' is zero. Thus, if I buy 100 shares
of RHAT for $5 and sell 100 shares of RHAT for $10, then
I *must* also add an 'adjusting transaction' for zero
shares of RHAT, at $500. If there is no adjusting transaction,
then the lot cannot be closed. If sum 'S' is zero,
while sum 'C' is not zero, then the lot is declared to
be 'out-of-balance', and an 'adjusting transaction' must
be forced.
It is only by 'closing a lot' that one is able to regain
'perfect balance' in the books. That is, the 'double-balance'
requirement is the generalization of the 'double-entry'
requirement for stock accounts.
Note that because the 'adjusting transaction' has one split
in dollars, and another split in RHAT shares (albeit for zero
RHAT shares), it evades the old double-entry requirement,
and will not be flagged as 'out of balance'. Note also
that because the 'adjusting transaction' contains a split
holding S (albeit zero S), it *must* be a part of a Lot.
The above seems to work for simple stock-transactions, but
fails in other more complex cases. Here's an example.
Imagine 'S' is in euros, instead of 'RHAT'. So I sell
100 dollars, and buy 110 euros. This causes a lot to open
up for the euros, with the lot currency 'L' in dollars.
Now I try to transfer the euros to other euro accounts.
What happens to the lot? Do I have to give up on it?
How can I save this bad situation?
A similar problem occurs for more complex stock transactions:
If I buy 100 shares of RHAT with Schwab, and transfer them
to another account with Etrade, then I have the same lot
closing problem. There's an even worse scenario, where
I move to Brazil, and take my RHAT stock (purchased in dollars)
to my Brazilian broker (who will sell them for cruzeiros).
Is the correct answer to just 'punt' in these cases?
How is the closing of books to be handled in such a case?
GUI Elements:
- The user should be able to specify a default 'realized-gain'
account that is associated with a stock account.
- The user should be able to specify a default 'unrealized-gain'
account that is associated with a stock account.
\section lotsfifo FIFO's
What is a FIFO ? A FIFO is a type of accounting policy where
income from selling inventory is accounted by selling the oldest
inventory first. Thus, the profit/loss of the sale corresponds
to the difference in price between when it was bought and sold.
FIFO's are also used in depreciation schedules, and in other places.
Currently the only policy that is implemented in the cap-gains
code is the FIFO policy. I believe that it's been abstracted
properly, so that it should be easy to add other policies,
e.g. LIFO. See policy.c for what would need to be implemented.
\section lotsimplement Implementation
Every split has a pointer to a lot (which may be null). A lot has a list
of splits in it (so that the other splits in the lot can be easily found).
A lot does not need to maintain a balance (this is easy enough to calculate
on the fly). A lot has a kvp tree (for storage of lot-related date, such
as due dates for invoices, etc. A lot has a GUID.
From the memory-management and data-base management point of view, lots
belong to accounts. The GnuCash account structure maintains a list of
lots so that all lots belonging to an account can be quickly retrieved.
(In principle, the lots can be found by scanning every split in the
account, but this is a painful process.)
\section lotscapgains Implementing Cap Gains (Is a Pain in the Neck)
Although Lots provide a good conceptual framework for determining
gains or losses when a lot is closed, cap-gains on half-open
lots present additional complexities. Consider the following
stock purchase and subsequent sale of half the stock:
Account A is a stock account
Account B is a bank account
Account C is an income account
\verbatim
Acct A Txn Acct B Acct C
Date Action Amt Prc Value Amt Amt
1/1/01 buy 100s $10 $1000 ($1000) -
2/2/02 sell (50)s $25 $1250 $1250 -
2/2/02 gain - - $750 $750
\endverbatim
The gain, shown in the third line, is computed as a straight
sum of purchase price to sale price.
Should the above be represented as two transactions, or as three?
One could, in principle, combine the second and third lines into
one transaction. However, this has some drawbacks: computing
the overall balance of such a transaction is tricky, because
it has so many different splits (including, possibly, splits
for brokerage fees, tax, etc. not shown). The alternative
is to represent each line as a separate transaction. This has
other drawbacks: If the date, amount, price or value is adjusted
for the second transaction, the corresponding values must be
adjusted for the third, and vice-versa.
Both schemes pose trouble for the register display: we want
the stock register to show the gain as if it were a part of
the stock sale; but the third line is a pair of splits, and
we want to show only one of these two splits. Whichever method
is chosen, the register has to filter out some of the splits
that it shows.
The implementation that seems best is to represent the sale
with two separate transactions: one for the sale itself, and a
separate one for the gains. This makes computing the balance
easier, although it makes the logic for setting the date
more complex. Ughh..
\section loanscapnotes Cap Gains Implementation Notes
Cap Gains will be handled by GnuCash as described above, using
two distinct transactions. These transactions will be marked up
using KVP, pointing to each other, so that the one can be found
from the other. Implementation in src/engine/cap-gains.c
Quick API Overview:
- xaccSplitGetCapGains(): Returns the capital gains associated with
a split. Split must have been a sale/purchase in a previously
opened lot.
- xaccSplitAssignToLot(): If a split is not already in a lot,
then it places it into a lot, using a FIFO accounting policy.
\section lotscapimplement Cap Gains Actual Implementation
Cap Gains are noted by creating a separate transaction with two
splits in it. One of the splits is as described above: zero
amount, non-zero value. There is a GUI requirement that when
the looking at a gains transaction, certain things need to be
kept in sync with the transaction that is the source of the gains.
In order to accomplish this, the engine uses a set of 'dirty'
flags, and a pair of pointers between the gains split and the
source split, so that the one can be quickly found from the other.
Things kept in sync:
- date posted
- value
- void status
- other things ?
Things not kept in sync:
- kvp trees
- description, memo, action.
The posted date is kept in sync using a data-constraint scheme.
If xaccTransactionSetDatePosted() is called, the date change is
accepted, and the split is marked date-dirty. When the transaction
is committed (using xaccTransCommitEdit()), the date-dirty flag
is evaluated, and, if needed, the date changes are propagated/rolled
back on the appropriate gains splits. Currently, one can only change
the date on the gains-source transaction; the date on the
gains-recording split cannot be changed.
The value recorded by the gains transaction is updated whenever
the value of the source changes. The actual update is done by
the xaccSplitComputeCapGains() routine, via xaccScrubLot(), which
is called at the time of xaccTransCommitEdit(). Note that two
different things can affect the gains: a change in the value of
the sale, and a change of the value of the purchase. A set of
dirty flags are used to track these.
If the amount of a split changes, then the lot that its in becomes
potentially unbalanced. This requires the lot membership to be
recomputed; this in turn may require the split to be split into
pieces, or to be recombined into one from several pieces.
\section lotsconversion Conversion
As Lots are put into production, old GnuCash datasets
will need to be converted. Conversion will be done by running
all splits in an account through an accounting policy (currently,
there is only one policy, a FIFO). The goal of the policy is to
match up purchases and sales so that these can be assigned to a Lot.
The conversion algorithm will work as follows:
\verbatim
for each account {
loop over splits {
// perform the 'double-balance' check
if (split commodity != transaction currency) account needs conversion
}
if account needs conversion
for each split {
If (split amount > 0) create new lot, put split in lot.
If (split amount < 0) find oldest lot, put split in that lot
}
}
\endverbatim
See the file Scrub2.h for details of the low-level API, and Scrub3.h
for the high-level API.
There is a bit of a problem with this conversion procedure: If the
user had previously recorded cap gains using a 'handmade' version of
lots, those cap gains will be ignored and will throw off balances.
User will need to hand-edit to recover.
*/

View File

@ -27,9 +27,47 @@
* @author Copyright (C) 2002 Derek Atkins
* @author Derek Atkins <warlord@MIT.EDU>
*/
/**
@page ImmutableTaxTableBillTerm Some notes on tracking fields in gncBillTerm and gncTaxTable objects
The gncTaxTable and gncBillTerm business objects have parent, child,
refcount, invisible field in their structures that deserve some
explanation:
- a child is a 'frozen' instance of a parent. For example, the tax
percentage in a particular tax table may change over time, but you
dont want that change to affect already-posted invoices... So you
make sure there is an immutable 'copy' (read: child) of the tax
table when you post the invoice and repoint at the child.
- a parent can have many children, but it will only have a 'child'
pointer if the parent has not been modified. Think of this as a
copy-on-write mechanism. posted invoices will continue to use the
_same_ child until the parent is modified, at which point a new
child will be created.
- invisible means "dont show this in the list". It's so you dont
get all the children in the tax table list -- you only see parents.
I suppose this flag could also be called "is-child" as I believe that
only children can be invisible, and ALL children are invisible.
- refcount is a listing of how many objects are referencing it.
Basically, it's letting you know how many customer, vendor, entries,
etc are referencing e.g. a particular tax table object. mostly this
was done to make sure you cannot delete an in-use taxtable.
- children don't use refcounts, only parents do.
- A child always points to its parent (it can have only 1).
- A parent has a list of all children.
- A parent has a pointer to the current 'replica child', if one exists.
*/
/** @} */
/** @} */
#ifndef GNC_BUSINESS_H_
#define GNC_BUSINESS_H_

View File

@ -22,6 +22,13 @@
/** @addtogroup Business
@{ */
/** @addtogroup TaxTable
Define an object to track tax properties for invoices.
@note A tax table added to an invoice is immutable, that is it
can't change any more. To achieve that a tax table is copied when
added to an invoice. This uses some internal fields to track this which
are explained in @ref ImmutableTaxTableBillTerm.
@{ */
/** @file gncTaxTable.h
@brief Tax Table programming interface