[Gnucash-changes] Sync the g2 branch with the gnome2-merge-10 tag.
David Hampton
hampton at cvs.gnucash.org
Wed Aug 25 18:46:46 EDT 2004
Log Message:
-----------
Sync the g2 branch with the gnome2-merge-10 tag. (2004-08-25)
Tags:
----
gnucash-gnome2-dev
Modified Files:
--------------
gnucash:
ChangeLog
GNOME2_STATUS
gnucash/src/business/business-core:
gncAddress.c
gncBillTerm.c
gncBillTerm.h
gncCustomer.c
gncCustomer.h
gncEmployee.c
gncEmployee.h
gncEntry.c
gncInvoice.c
gncJob.c
gncOrder.c
gncTaxTable.c
gncTaxTable.h
gncVendor.c
gnucash/src/doc/design:
engine.texinfo
gnucash/src/engine:
Account.c
Account.h
Group.c
Scrub.c
Scrub2.c
Transaction.c
Transaction.h
cap-gains.c
cap-gains.h
gnc-lot.c
gnc-lot.h
gnc-numeric.c
gnc-pricedb.c
kvp-util.c
kvp_frame.c
qof-be-utils.h
qofbackend-p.h
qofbook.h
qofid.c
qofid.h
qofmath128.c
qofquery.c
qofsession.c
gnucash/src/engine/test:
test-lots.c
test-numeric.c
test-transaction-reversal.c
gnucash/src/engine/test-core:
test-engine-stuff.c
gnucash/src/gnome:
gnucash.desktop.in
gnucash/src/import-export/qif-import:
qif-dialog-utils.scm
gnucash/src/report/report-system:
commodity-utilities.scm
html-acct-table.scm
html-table.scm
report-system.scm
report-utilities.scm
gnucash/src/report/standard-reports:
Makefile.am
advanced-portfolio.scm
balance-sheet.scm
equity-statement.scm
standard-reports.scm
transaction.scm
Added Files:
-----------
gnucash/src:
count.dat
count.gplot
gnucash/src/report/standard-reports:
general-journal.scm
general-ledger.scm
income-statement.scm
trial-balance.scm
Removed Files:
-------------
gnucash/src/report/standard-reports:
pnl.scm
Revision Data
-------------
Index: ChangeLog
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/ChangeLog,v
retrieving revision 1.1487.2.136
retrieving revision 1.1487.2.137
diff -LChangeLog -LChangeLog -u -r1.1487.2.136 -r1.1487.2.137
--- ChangeLog
+++ ChangeLog
@@ -2702,6 +2702,140 @@
-=-=-=- cvs HEAD ChangeLog is below this line -=-=-=-
+2004-18-21 Derek Atkins <derek at ihtfp.com>
+
+ * src/report/standard-reports/advanced-portfolio.scm:
+ Add option to include zero-amount splits in computations.
+ Fixes #143722.
+
+2004-18-19 Derek Atkins <derek at ihtfp.com>
+
+ Neil Williams's "QOF create: functionality added" patch:
+
+ QOF create: adding functions to be used with
+ qof_object_new_instance for new qof_book_merge objects, including
+ business objects.
+
+ Small documentation tweak to make QofEntity and QofParam
+ structures visible to doxygen.
+
+ * src/import-export/qif-import/qif-dialog-utils.scm:
+ Perry Smith's Null Account Patch. Make sure the security is
+ a real string before appending an account separator, so we
+ don't try to create a "null" account.
+
+2004-08-19 Derek Atkins <derek at ihtfp.com>
+
+ * configure.in: change the gtkhtml order to search for >= 1.1 before
+ < 1.1, in order to try to fix #84707 on systems with multiple
+ versions of gtkhtml.
+
+2004-08-12 David Montenegro <sunrise2000 at comcast.net>
+
+ * src/report/standard-reports/trial-balance.scm:
+ src/report/standard-reports/equity-statement.scm:
+ src/report/report-system/report-utilities.scm:
+ Added to the work sheet special handling of
+ inventory and income summary accounts for
+ merchandising businesses. Fixes #150008.
+
+2004-08-11 Derek Atkins <derek at ihtfp.com>
+
+ * src/gnome/gnucash.desktop.in: make the desktop HIG compliant.
+ Fixes #145545
+
+2004-07-20 Derek Atkins <derek at ihtfp.com>
+
+ * src/engine/Scrub.c
+ * src/engine/Scrub2.c
+ * src/engine/gnc-numeric.c
+ * src/engine/gnc-pricedb.c
+ * src/engine/kvp-util.c
+ * src/engine/qofid.c
+ * src/engine/qofmath128.c
+ * src/engine/qofquery.c
+ * src/engine/qofsession.c
+ * src/engine/test/test-numeric.c
+ Priit Laes' patch for C90 compliance.
+
+2004-07-13 David Montenegro <sunrise2000 at comcast.net>
+
+ * src/report/standard-reports/general-ledger.scm:
+ src/report/standard-reports/standard-reports.scm:
+ src/report/standard-reports/Makefile.am:
+ Added General Ledger report, a Transaction Report
+ with a pre-set set of options.
+
+ * src/report/standard-reports/transaction.scm:
+ FIXME - All accounts now selected by default, avoids
+ confusing error message. Error message also clarified.
+ Fixed "Totals" option so that it works.
+
+ * src/report/standard-reports/balance-sheet.scm:
+ * src/report/standard-reports/equity-statement.scm:
+ * src/report/standard-reports/trial-balance.scm:
+ Updated comments
+ * Fixes #144268
+
+ * src/report/standard-reports/income-statement.scm:
+ src/report/standard-reports/pnl.scm:
+ src/report/standard-reports/standard-reports.scm:
+ src/report/standard-reports/Makefile.am:
+ Rewrote pnl.scm, renamed it to income-statement.scm.
+ Can now create a meaningful statement post-closing.
+
+ * src/report/report-system/html-acct-table.scm:
+ Updated to include ability to "see through" closing
+ and/or adjusting entries.
+ * Fixes #105330.
+
+ * src/report/standard-reports/general-journal.scm:
+ src/report/standard-reports/standard-reports.scm:
+ src/report/standard-reports/Makefile.am:
+ Added General Journal report, a Register Report
+ with a pre-set set of options.
+ * Bug #109738.
+
+2004-07-13 David Montenegro <sunrise2000 at comcast.net>
+
+ * src/report/standard-reports/trial-balance.scm:
+ * src/report/standard-reports/standard-reports.scm:
+ * src/report/standard-reports/Makefile.am
+ added Trial Balance/Work Sheet report
+
+ * src/report/standard-reports/balance-sheet.scm:
+ added drop-down choices missing in previous version
+ added support for adjusting/closing entries
+
+ * src/report/standard-reports/equity-statement.scm:
+ added support for adjusting/closing entries
+ fixed "For Period Covering" label
+ fixed handling of unrealized gains
+ investment/draw discrimination based on shares sign
+ omit unrealized gains when zero
+
+ * src/report/report-system/html-acct-table.scm:
+ * src/report/report-system/html-table.scm:
+ null reference bug fixes
+
+ * src/report/report-system/report-utilities.scm:
+ added utility functions for accessing splits
+ and creating double-column balance HTML
+ gnc:double-col,
+ gnc:account-get-trans-type-balance-interval,
+ gnc:account-get-pos-trans-total-interval
+
+ * src/report/report-system/commodity-utilities.scm:
+ * src/report/report-system/html-acct-table.scm:
+ * src/report/report-system/report-utilities.scm:
+ moved gnc:commodity-collector-commodity-count and
+ gnc:uniform-commodity? into commodity-utilities.scm
+
+ * src/report/report-system/report-system.scm:
+ added some additional exports
+
+ Bug #144265
+
2004-07-04 Derek Atkins <derek at ihtfp.com>
* acinclude.m4: create a SCANF_QD_CHECK and make sure both
Index: GNOME2_STATUS
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/Attic/GNOME2_STATUS,v
retrieving revision 1.1.2.26
retrieving revision 1.1.2.27
diff -LGNOME2_STATUS -LGNOME2_STATUS -u -r1.1.2.26 -r1.1.2.27
--- GNOME2_STATUS
+++ GNOME2_STATUS
@@ -13,7 +13,7 @@
names of active developers, that'd be great.
========================================
- Last sync with HEAD on 2004-07-05
+ Last sync with HEAD on 2004-08-25
========================================
========================================
Index: Scrub2.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/Scrub2.c,v
retrieving revision 1.15.2.3
retrieving revision 1.15.2.4
diff -Lsrc/engine/Scrub2.c -Lsrc/engine/Scrub2.c -u -r1.15.2.3 -r1.15.2.4
--- src/engine/Scrub2.c
+++ src/engine/Scrub2.c
@@ -156,6 +156,7 @@
{
gnc_commodity *currency = NULL;
SplitList *snode;
+ GList *node;
gnc_numeric zero = gnc_numeric_zero();
gnc_numeric value = zero;
@@ -211,7 +212,6 @@
*/
PERR ("Closed lot fails to double-balance !! lot value=%s",
gnc_num_dbg_to_string (value));
- GList *node;
for (node=lot->splits; node; node=node->next)
{
Split *s = node->data;
Index: qofquery.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofquery.c,v
retrieving revision 1.10.2.5
retrieving revision 1.10.2.6
diff -Lsrc/engine/qofquery.c -Lsrc/engine/qofquery.c -u -r1.10.2.5 -r1.10.2.6
--- src/engine/qofquery.c
+++ src/engine/qofquery.c
@@ -1236,13 +1236,13 @@
void qof_query_set_book (QofQuery *q, QofBook *book)
{
+ GSList *slist = NULL;
if (!q || !book) return;
/* Make sure this book is only in the list once */
if (g_list_index (q->books, book) == -1)
q->books = g_list_prepend (q->books, book);
- GSList *slist = NULL;
g_slist_prepend (slist, QOF_PARAM_GUID);
g_slist_prepend (slist, QOF_PARAM_BOOK);
qof_query_add_guid_match (q, slist,
Index: qofmath128.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofmath128.c,v
retrieving revision 1.6.2.1
retrieving revision 1.6.2.2
diff -Lsrc/engine/qofmath128.c -Lsrc/engine/qofmath128.c -u -r1.6.2.1 -r1.6.2.2
--- src/engine/qofmath128.c
+++ src/engine/qofmath128.c
@@ -43,6 +43,13 @@
mult128 (gint64 a, gint64 b)
{
qofint128 prod;
+ guint64 a0, a1;
+ guint64 b0, b1;
+ guint64 d, d0, d1;
+ guint64 e, e0, e1;
+ guint64 f, f0, f1;
+ guint64 g, g0, g1;
+ guint64 sum, carry, roll, pmax;
prod.isneg = 0;
if (0>a)
@@ -57,35 +64,35 @@
b = -b;
}
- guint64 a1 = a >> 32;
- guint64 a0 = a - (a1<<32);
+ a1 = a >> 32;
+ a0 = a - (a1<<32);
- guint64 b1 = b >> 32;
- guint64 b0 = b - (b1<<32);
+ b1 = b >> 32;
+ b0 = b - (b1<<32);
- guint64 d = a0*b0;
- guint64 d1 = d >> 32;
- guint64 d0 = d - (d1<<32);
-
- guint64 e = a0*b1;
- guint64 e1 = e >> 32;
- guint64 e0 = e - (e1<<32);
-
- guint64 f = a1*b0;
- guint64 f1 = f >> 32;
- guint64 f0 = f - (f1<<32);
-
- guint64 g = a1*b1;
- guint64 g1 = g >> 32;
- guint64 g0 = g - (g1<<32);
+ d = a0*b0;
+ d1 = d >> 32;
+ d0 = d - (d1<<32);
+
+ e = a0*b1;
+ e1 = e >> 32;
+ e0 = e - (e1<<32);
+
+ f = a1*b0;
+ f1 = f >> 32;
+ f0 = f - (f1<<32);
+
+ g = a1*b1;
+ g1 = g >> 32;
+ g0 = g - (g1<<32);
- guint64 sum = d1+e0+f0;
- guint64 carry = 0;
+ sum = d1+e0+f0;
+ carry = 0;
/* Can't say 1<<32 cause cpp will goof it up; 1ULL<<32 might work */
- guint64 roll = 1<<30;
+ roll = 1<<30;
roll <<= 2;
- guint64 pmax = roll-1;
+ pmax = roll-1;
while (pmax < sum)
{
sum -= roll;
@@ -125,7 +132,8 @@
inline qofint128
shiftleft128 (qofint128 x)
{
- guint64 sbit = x.lo & HIBIT;
+ guint64 sbit;
+ sbit = x.lo & HIBIT;
x.hi <<= 1;
x.lo <<= 1;
x.isbig = 0;
@@ -174,6 +182,7 @@
div128 (qofint128 n, gint64 d)
{
qofint128 quotient;
+ int i;
guint64 remainder = 0;
quotient = n;
@@ -184,7 +193,6 @@
}
/* Use grade-school long division algorithm */
- int i;
for (i=0; i<128; i++)
{
guint64 sbit = HIBIT & quotient.hi;
Index: qofid.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofid.h,v
retrieving revision 1.2.6.4
retrieving revision 1.2.6.5
diff -Lsrc/engine/qofid.h -Lsrc/engine/qofid.h -u -r1.2.6.4 -r1.2.6.5
--- src/engine/qofid.h
+++ src/engine/qofid.h
@@ -69,7 +69,9 @@
#include <string.h>
#include "guid.h"
+/** QofIdType declaration */
typedef const char * QofIdType;
+/** QofIdTypeConst declaration */
typedef const char * QofIdTypeConst;
#define QOF_ID_NONE NULL
@@ -112,10 +114,25 @@
(obj); \
}))
-
+/** QofEntity declaration */
typedef struct QofEntity_s QofEntity;
+/** QofCollection declaration
+
+ at param e_type QofIdType
+ at param is_dirty gboolean
+ at param hash_of_entities GHashTable
+ at param data gpointer, place where object class can hang arbitrari data
+
+*/
typedef struct QofCollection_s QofCollection;
+/** QofEntity structure
+
+ at param e_type Entity type
+ at param guid GUID for the entity
+ at param collection Entity collection
+*/
+
struct QofEntity_s
{
QofIdType e_type;
@@ -171,4 +188,3 @@
#endif /* QOF_ID_H */
/** @} */
/** @} */
-
Index: Scrub.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/Scrub.c,v
retrieving revision 1.43.4.4
retrieving revision 1.43.4.5
diff -Lsrc/engine/Scrub.c -Lsrc/engine/Scrub.c -u -r1.43.4.4 -r1.43.4.5
--- src/engine/Scrub.c
+++ src/engine/Scrub.c
@@ -137,6 +137,8 @@
xaccTransScrubOrphans (Transaction *trans)
{
SplitList *node;
+ QofBook *book = NULL;
+ AccountGroup *root = NULL;
for (node = trans->splits; node; node = node->next)
{
Split *split = node->data;
@@ -154,8 +156,8 @@
* XXX we should probably *always* to this, instead of the above loop!
*/
PINFO ("Free Floating Transaction!");
- QofBook *book = xaccTransGetBook (trans);
- AccountGroup *root = xaccGetAccountGroup (book);
+ book = xaccTransGetBook (trans);
+ root = xaccGetAccountGroup (book);
TransScrubOrphansFast (trans, root);
}
@@ -198,13 +200,22 @@
void
xaccTransScrubSplits (Transaction *trans)
{
+ gnc_commodity *currency;
GList *node;
- if (!trans)
- return;
+ if (!trans) return;
+
+ /* The split scrub expects the transaction to have a currency! */
+ currency = xaccTransGetCurrency (trans);
+ if (!currency)
+ {
+ PERR ("Transaction doesn't have a currency!");
+ }
for (node = trans->splits; node; node = node->next)
+ {
xaccSplitScrub (node->data);
+ }
}
void
@@ -212,11 +223,12 @@
{
Account *account;
Transaction *trans;
- gnc_numeric value;
+ gnc_numeric value, amount;
gnc_commodity *currency;
int scu;
if (!split) return;
+ ENTER ("(split=%p)", split);
trans = xaccSplitGetParent (split);
if (!trans) return;
@@ -242,6 +254,21 @@
return;
}
+ /* Split amounts and values should be valid numbers */
+ value = xaccSplitGetValue (split);
+ if (gnc_numeric_check (value))
+ {
+ value = gnc_numeric_zero();
+ xaccSplitSetValue (split, value);
+ }
+
+ amount = xaccSplitGetAmount (split);
+ if (gnc_numeric_check (amount))
+ {
+ amount = gnc_numeric_zero();
+ xaccSplitSetAmount (split, amount);
+ }
+
currency = xaccTransGetCurrency (trans);
/* If the account doesn't have a commodity,
@@ -251,16 +278,17 @@
{
xaccAccountScrubCommodity (account);
}
- if (!account->commodity || !gnc_commodity_equiv (account->commodity, currency))
+ if (!account->commodity ||
+ !gnc_commodity_equiv (account->commodity, currency))
+ {
+ LEAVE ("(split=%p) inequiv currency", split);
return;
+ }
scu = MIN (xaccAccountGetCommoditySCU (account),
gnc_commodity_get_fraction (currency));
- value = xaccSplitGetValue (split);
-
- if (gnc_numeric_same (xaccSplitGetAmount (split),
- value, scu, GNC_HOW_RND_ROUND))
+ if (gnc_numeric_same (amount, value, scu, GNC_HOW_RND_ROUND))
{
return;
}
@@ -279,6 +307,7 @@
xaccTransBeginEdit (trans);
xaccSplitSetAmount (split, value);
xaccTransCommitEdit (trans);
+ LEAVE ("(split=%p)", split);
}
/* ================================================================ */
@@ -334,12 +363,14 @@
Account *parent)
{
Split *balance_split = NULL;
+ QofBook *book = NULL;
gnc_numeric imbalance;
Account *account;
SplitList *node, *slist;
if (!trans) return;
+ ENTER ("()");
xaccTransScrubSplits (trans);
/* If the transaction is balanced, nothing more to do */
@@ -366,7 +397,7 @@
/* This should never occur, accounts are always
* in an account group */
PERR ("Can't find root account");
- QofBook *book = xaccTransGetBook (trans);
+ book = xaccTransGetBook (trans);
root = xaccGetAccountGroup (book);
}
if (NULL == root)
@@ -442,6 +473,7 @@
xaccSplitScrub (balance_split);
xaccTransCommitEdit (trans);
}
+ LEAVE ("()");
}
/* ================================================================ */
Index: Group.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/Group.c,v
retrieving revision 1.112.4.6
retrieving revision 1.112.4.7
diff -Lsrc/engine/Group.c -Lsrc/engine/Group.c -u -r1.112.4.6 -r1.112.4.7
--- src/engine/Group.c
+++ src/engine/Group.c
@@ -1267,7 +1267,7 @@
interface_version: QOF_OBJECT_VERSION,
e_type: GNC_ID_GROUP,
type_label: "AccountGroup",
- create: NULL,
+ create: (gpointer)xaccMallocAccountGroup,
book_begin: group_book_begin,
book_end: group_book_end,
is_dirty: group_is_dirty,
Index: cap-gains.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/cap-gains.h,v
retrieving revision 1.4.4.2
retrieving revision 1.4.4.3
diff -Lsrc/engine/cap-gains.h -Lsrc/engine/cap-gains.h -u -r1.4.4.2 -r1.4.4.3
--- src/engine/cap-gains.h
+++ src/engine/cap-gains.h
@@ -26,15 +26,49 @@
* This file implements the various routines to automatically
* compute and handle Cap Gains/Losses resulting from trading
* activities. Some of these routines might have broader
- * applicability, for handling depreciation * & etc.
+ * applicability, for handling depreciation & etc.
*
- * This code is under development, and is 'alpha': many important
- * routines are missing, many existing routines are not called
- * from inside the engine as needed, and routines may be buggy.
+ * This code is under development, and is 'beta': we think we're
+ * mostly done, and we've tested and "things work for us", but there
+ * may still be something missing, and there might still be some
+ * bugs.
*
* This code does not currently handle tax distinctions, e.g
* the different tax treatment that short-term and long-term
* cap gains have.
+ *
+ * The computation of (Realized) Gains/Losses is performed automatically by
+ * the lot "scrub" routines, using a "double-balance" algorithm. Every
+ * split has two numbers associated with it: an "amount", which is the
+ * number of items that a split describes, and the "value", which is the
+ * cost of those items. In a closed lot, the grand-total amount of items in
+ * the lot is zero: the number of items bought equals the number of items
+ * sold; thus the amount-balance is zero. But since the purchase/sale of
+ * the items in the lot typically happen at different prices, there will
+ * typically be a gain/loss. This gain/loss is the grand-total value of all
+ * the items in the lot (total costs minus total income).
+ *
+ * In order to properly account for the gains/losses, an "adjusting split"
+ * is added that brings the total gains/losses back to exactly zero (this
+ * is the second "balance" of "double balance"). This adjusting split will
+ * have an amount of zero (no items are involved) but have a non-zero value
+ * (equal to the total gain/loss). This split can then participate in a
+ * "gains transaction" which records the gains in another account. Thus,
+ * for example, if you record $300 in your bank account due to the purchase
+ * and then the sale of some item, the "gains transaction" will record $300
+ * in income in an income account. Thus, the change in the bank balance is
+ * always reflected by an equal change in income, assuring that the books
+ * are balanced.
+ *
+ * Notes about auto-recompute: If the amount in a split is changed,
+ * then the lot has to be recomputed.
+ * This has a potential trickle-through effect on all later lots.
+ * Ideally, later lots are dissolved, and recomputed. However, some
+ * lots may have been user-hand-built. These should be left alone.
+ *
+ToDo:
+ o XXX Need to create a data-integrity scrubber, tht makes sure that
+ the various flags, and pointers & etc. match.
* @{ */
/** @file cap-gains.h
Index: gnc-numeric.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/gnc-numeric.c,v
retrieving revision 1.26.4.4
retrieving revision 1.26.4.5
diff -Lsrc/engine/gnc-numeric.c -Lsrc/engine/gnc-numeric.c -u -r1.26.4.4 -r1.26.4.5
--- src/engine/gnc-numeric.c
+++ src/engine/gnc-numeric.c
@@ -82,6 +82,7 @@
static inline gint64
gnc_numeric_lcd(gnc_numeric a, gnc_numeric b)
{
+ qofint128 lcm;
if(gnc_numeric_check(a) || gnc_numeric_check(b))
{
return GNC_ERROR_ARG;
@@ -99,7 +100,7 @@
return b.denom;
}
- qofint128 lcm = lcm128 (a.denom, b.denom);
+ lcm = lcm128 (a.denom, b.denom);
if (lcm.isbig) return GNC_ERROR_ARG;
return lcm.lo;
}
@@ -113,6 +114,7 @@
gint64 num;
gint64 denom;
gnc_numeric out;
+ qofint128 red;
t = rem128 (n, d);
num = d;
@@ -127,7 +129,7 @@
}
/* num now holds the GCD (Greatest Common Divisor) */
- qofint128 red = div128 (n, num);
+ red = div128 (n, num);
if (red.isbig)
{
return gnc_numeric_error (GNC_ERROR_OVERFLOW);
@@ -219,6 +221,7 @@
gnc_numeric_compare(gnc_numeric a, gnc_numeric b)
{
gint64 aa, bb;
+ qofint128 l, r;
if(gnc_numeric_check(a) || gnc_numeric_check(b))
{
@@ -235,8 +238,8 @@
if ((a.denom > 0) && (b.denom > 0))
{
/* Avoid overflows using 128-bit intermediate math */
- qofint128 l = mult128 (a.num, b.denom);
- qofint128 r = mult128 (b.num, a.denom);
+ l = mult128 (a.num, b.denom);
+ r = mult128 (b.num, a.denom);
return cmp128 (l,r);
}
@@ -377,18 +380,19 @@
* Computing the LCD minimizes likelyhood of overflow
*/
gint64 lcd;
+ qofint128 ca, cb, cab;
lcd = gnc_numeric_lcd(a,b);
if (GNC_ERROR_ARG == lcd)
{
return gnc_numeric_error(GNC_ERROR_OVERFLOW);
}
- qofint128 ca = mult128 (a.num, lcd/a.denom);
+ ca = mult128 (a.num, lcd/a.denom);
if (ca.isbig) return gnc_numeric_error(GNC_ERROR_OVERFLOW);
- qofint128 cb = mult128 (b.num, lcd/b.denom);
+ cb = mult128 (b.num, lcd/b.denom);
if (cb.isbig) return gnc_numeric_error(GNC_ERROR_OVERFLOW);
- qofint128 cab = add128 (ca, cb);
+ cab = add128 (ca, cb);
if (cab.isbig) return gnc_numeric_error(GNC_ERROR_OVERFLOW);
sum.num = cab.lo;
@@ -414,12 +418,13 @@
gnc_numeric_sub(gnc_numeric a, gnc_numeric b,
gint64 denom, gint how)
{
+ gnc_numeric nb;
if(gnc_numeric_check(a) || gnc_numeric_check(b))
{
return gnc_numeric_error(GNC_ERROR_ARG);
}
- gnc_numeric nb = b;
+ nb = b;
nb.num = -nb.num;
return gnc_numeric_add (a, nb, denom, how);
}
@@ -455,6 +460,13 @@
}
}
+ if((denom == GNC_DENOM_AUTO) &&
+ ((how & GNC_NUMERIC_DENOM_MASK) == GNC_HOW_DENOM_LCD))
+ {
+ denom = gnc_numeric_lcd(a, b);
+ how = how & GNC_NUMERIC_RND_MASK;
+ }
+
if(a.denom < 0) {
a.num *= a.denom;
a.denom = 1;
@@ -473,6 +485,24 @@
/* If it looks to be overflowing, try to reduce the fraction ... */
if (bignume.isbig || bigdeno.isbig)
{
+ gint64 tmp;
+ a = gnc_numeric_reduce (a);
+ b = gnc_numeric_reduce (b);
+ tmp = a.num;
+ a.num = b.num;
+ b.num = tmp;
+ a = gnc_numeric_reduce (a);
+ b = gnc_numeric_reduce (b);
+
+ bignume = mult128 (a.num, b.num);
+ bigdeno = mult128 (a.denom, b.denom);
+ product.num = a.num*b.num;
+ product.denom = a.denom*b.denom;
+ }
+
+ /* If it its still overflowing, and rounding is allowed then round */
+ if (bignume.isbig || bigdeno.isbig)
+ {
/* If rounding allowed, then shift until there's no
* more overflow. The conversion at the end will fix
* things up for the final value. Else overflow. */
@@ -513,13 +543,6 @@
}
#endif
- if((denom == GNC_DENOM_AUTO) &&
- ((how & GNC_NUMERIC_DENOM_MASK) == GNC_HOW_DENOM_LCD))
- {
- denom = gnc_numeric_lcd(a, b);
- how = how & GNC_NUMERIC_RND_MASK;
- }
-
result = gnc_numeric_convert(product, denom, how);
return result;
}
@@ -534,6 +557,7 @@
gint64 denom, gint how)
{
gnc_numeric quotient;
+ qofint128 nume, deno;
if(gnc_numeric_check(a) || gnc_numeric_check(b))
{
@@ -588,60 +612,54 @@
sgn = -sgn;
b.num = -b.num;
}
- qofint128 nume = mult128(a.num, b.denom);
- qofint128 deno = mult128(b.num, a.denom);
+ nume = mult128(a.num, b.denom);
+ deno = mult128(b.num, a.denom);
+
+ /* Try to avoid overflow by removing common factors */
+ if (nume.isbig && deno.isbig)
+ {
+ gnc_numeric ra = gnc_numeric_reduce (a);
+ gnc_numeric rb = gnc_numeric_reduce (b);
+
+ gint64 gcf_nume = gcf64(ra.num, rb.num);
+ gint64 gcf_deno = gcf64(rb.denom, ra.denom);
+ nume = mult128(ra.num/gcf_nume, rb.denom/gcf_deno);
+ deno = mult128(rb.num/gcf_nume, ra.denom/gcf_deno);
+ }
+
if ((0 == nume.isbig) && (0 == deno.isbig))
{
quotient.num = sgn * nume.lo;
quotient.denom = deno.lo;
+ goto dive_done;
}
else if (0 == deno.isbig)
{
quotient = reduce128 (nume, deno.lo);
- quotient.num *= sgn;
- }
- else
- {
- /* Try to avoid overflow by removing common factors */
- gnc_numeric ra = gnc_numeric_reduce (a);
- gnc_numeric rb = gnc_numeric_reduce (b);
-
- gint64 gcf_nume = gcf64(ra.num, rb.num);
- gint64 gcf_deno = gcf64(rb.denom, ra.denom);
- qofint128 rnume = mult128(ra.num/gcf_nume, rb.denom/gcf_deno);
- qofint128 rdeno = mult128(rb.num/gcf_nume, ra.denom/gcf_deno);
-
- if ((0 == rnume.isbig) && (0 == rdeno.isbig))
- {
- quotient.num = sgn * rnume.lo;
- quotient.denom = rdeno.lo;
- }
- else if (0 == rdeno.isbig)
+ if (0 == gnc_numeric_check (quotient))
{
- quotient = reduce128 (rnume, rdeno.lo);
quotient.num *= sgn;
+ goto dive_done;
}
- else
- {
- /* If rounding allowed, then shift until there's no
- * more overflow. The conversion at the end will fix
- * things up for the final value. */
- if ((how & GNC_NUMERIC_RND_MASK) == GNC_HOW_RND_NEVER)
- {
- return gnc_numeric_error (GNC_ERROR_OVERFLOW);
- }
- while (rnume.isbig || rdeno.isbig)
- {
- rnume = shift128 (rnume);
- rdeno = shift128 (rdeno);
- }
- quotient.num = sgn * rnume.lo;
- quotient.denom = rdeno.lo;
- if (0 == quotient.denom)
- {
- return gnc_numeric_error (GNC_ERROR_OVERFLOW);
- }
- }
+ }
+
+ /* If rounding allowed, then shift until there's no
+ * more overflow. The conversion at the end will fix
+ * things up for the final value. */
+ if ((how & GNC_NUMERIC_RND_MASK) == GNC_HOW_RND_NEVER)
+ {
+ return gnc_numeric_error (GNC_ERROR_OVERFLOW);
+ }
+ while (nume.isbig || deno.isbig)
+ {
+ nume = shift128 (nume);
+ deno = shift128 (deno);
+ }
+ quotient.num = sgn * nume.lo;
+ quotient.denom = deno.lo;
+ if (0 == quotient.denom)
+ {
+ return gnc_numeric_error (GNC_ERROR_OVERFLOW);
}
}
@@ -651,6 +669,7 @@
quotient.denom = -quotient.denom;
}
+dive_done:
if((denom == GNC_DENOM_AUTO) &&
((how & GNC_NUMERIC_DENOM_MASK) == GNC_HOW_DENOM_LCD))
{
@@ -704,6 +723,7 @@
gint denom_neg=0;
double ratio, logratio;
double sigfigs;
+ qofint128 nume, newm;
if(gnc_numeric_check(in)) {
return gnc_numeric_error(GNC_ERROR_ARG);
@@ -800,8 +820,8 @@
* out.num = out.num / temp.denom;
* out.denom = denom;
*/
- qofint128 nume = mult128 (in.num, temp.num);
- qofint128 newm = div128 (nume, temp.denom);
+ nume = mult128 (in.num, temp.num);
+ newm = div128 (nume, temp.denom);
remainder = rem128 (nume, temp.denom);
if (newm.isbig)
Index: Account.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/Account.c,v
retrieving revision 1.222.4.6
retrieving revision 1.222.4.7
diff -Lsrc/engine/Account.c -Lsrc/engine/Account.c -u -r1.222.4.6 -r1.222.4.7
--- src/engine/Account.c
+++ src/engine/Account.c
@@ -2836,7 +2836,7 @@
interface_version: QOF_OBJECT_VERSION,
e_type: GNC_ID_ACCOUNT,
type_label: "Account",
- create: NULL,
+ create: (gpointer)xaccMallocAccount,
book_begin: NULL,
book_end: NULL,
is_dirty: NULL,
@@ -2849,16 +2849,16 @@
gboolean xaccAccountRegister (void)
{
static QofParam params[] = {
- { ACCOUNT_NAME_, QOF_TYPE_STRING, (QofAccessFunc)xaccAccountGetName, NULL },
- { ACCOUNT_CODE_, QOF_TYPE_STRING, (QofAccessFunc)xaccAccountGetCode, NULL },
- { ACCOUNT_DESCRIPTION_, QOF_TYPE_STRING, (QofAccessFunc)xaccAccountGetDescription, NULL },
- { ACCOUNT_NOTES_, QOF_TYPE_STRING, (QofAccessFunc)xaccAccountGetNotes, NULL },
+ { ACCOUNT_NAME_, QOF_TYPE_STRING, (QofAccessFunc)xaccAccountGetName, (QofSetterFunc) xaccAccountSetName },
+ { ACCOUNT_CODE_, QOF_TYPE_STRING, (QofAccessFunc)xaccAccountGetCode, (QofSetterFunc) xaccAccountSetCode },
+ { ACCOUNT_DESCRIPTION_, QOF_TYPE_STRING, (QofAccessFunc)xaccAccountGetDescription, (QofSetterFunc) xaccAccountSetDescription },
+ { ACCOUNT_NOTES_, QOF_TYPE_STRING, (QofAccessFunc)xaccAccountGetNotes, (QofSetterFunc) xaccAccountSetNotes },
{ ACCOUNT_PRESENT_, QOF_TYPE_NUMERIC, (QofAccessFunc)xaccAccountGetPresentBalance, NULL },
{ ACCOUNT_BALANCE_, QOF_TYPE_NUMERIC, (QofAccessFunc)xaccAccountGetBalance, NULL },
{ ACCOUNT_CLEARED_, QOF_TYPE_NUMERIC, (QofAccessFunc)xaccAccountGetClearedBalance, NULL },
{ ACCOUNT_RECONCILED_, QOF_TYPE_NUMERIC, (QofAccessFunc)xaccAccountGetReconciledBalance, NULL },
{ ACCOUNT_FUTURE_MINIMUM_, QOF_TYPE_NUMERIC, (QofAccessFunc)xaccAccountGetProjectedMinimumBalance, NULL },
- { ACCOUNT_TAX_RELATED, QOF_TYPE_BOOLEAN, (QofAccessFunc)xaccAccountGetTaxRelated, NULL },
+ { ACCOUNT_TAX_RELATED, QOF_TYPE_BOOLEAN, (QofAccessFunc)xaccAccountGetTaxRelated, (QofSetterFunc) xaccAccountSetTaxRelated },
{ QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
{ QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
{ ACCOUNT_KVP, QOF_TYPE_KVP, (QofAccessFunc)qof_instance_get_slots, NULL },
Index: Transaction.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/Transaction.h,v
retrieving revision 1.141.4.6
retrieving revision 1.141.4.7
diff -Lsrc/engine/Transaction.h -Lsrc/engine/Transaction.h -u -r1.141.4.6 -r1.141.4.7
--- src/engine/Transaction.h
+++ src/engine/Transaction.h
@@ -20,6 +20,62 @@
/** @addtogroup Engine
@{ */
/** @addtogroup Transaction Financial Transactions
+ A good overview of transactions, splits and accounts can be
+ found in the texinfo documentation, together with an overview of
+ how to use this API.
+
+Splits, or "Ledger Entries" are the fundamental
+accounting units. Each Split consists of an amount (number of dollar
+bills, number of shares, etc.), the value of that amount expressed in
+a (possibly) different currency than the amount, a Memo, a pointer to
+the parent Transaction, a pointer to the debited Account, a reconciled
+flag and timestamp, an "Action" field, and a key-value frame which can
+store arbitrary data.
+
+Transactions embody the notion of "double entry" accounting.
+A Transaction consists of a date, a description, an ID number,
+a list of one or more Splits, and a key-value frame. The transaction
+also specifies the currency with which all of the splits will be valued.
+When double-entry rules are enforced, the sum total value of the splits
+are zero. If there are only two splits, then the value of one must be
+positive, the other negative: this denotes that one account is debited,
+and another is credited by an equal amount. By forcing the value of the
+splits to always 'add up' to zero, we can gaurentee that the balances
+of the accounts are always correctly balanced.
+
+The engine does not enforce double-entry accounting, but provides an API
+to enable user-code to find unbalanced transactions and 'repair' them so
+that they are in balance.
+
+Note the sum of the values of Splits in a Transaction is always computed
+with respect to a currency; thus splits can be balanced even when they
+are in different currencies, as long as they share a common currency.
+This feature allows currency-trading accounts to be established.
+
+Every Split must point to its parent Transaction, and that Transaction
+must in turn include that Split in the Transaction's list of Splits. A
+Split can belong to at most one Transaction. These relationships are
+enforced by the engine. The engine user cannnot accidentally destroy
+this relationship as long as they stick to using the API and never
+access internal structures directly.
+
+Splits are grouped into Accounts which are also known
+as "Ledgers" in accounting practice. Each Account consists of a list of
+Splits that debit that Account. To ensure consistency, if a Split points
+to an Account, then the Account must point to the Split, and vice-versa.
+A Split can belong to at most one Account. Besides merely containing a
+list of Splits, the Account structure also gives the Account a name, a
+code number, description and notes fields, a key-value frame, a pointer
+to the commodity that is used for all splits in this account. The
+commodity can be the name of anything traded and tradable: a stock
+(e.g. "IBM", "McDonald's"), a currency (e.g. "USD", "GBP"), or anything
+added to the commodity table.
+
+Accounts can be arranged in a hierarchical tree. The nodes of the tree
+are called "Account Groups". By accounting
+convention, the value of an Account is equal to the value of all of its
+Splits plus the value of all of its sub-Accounts.
+
@{ */
/** @file Transaction.h
@brief API for Transactions and Splits (journal entries)
@@ -60,12 +116,11 @@
#define TXN_TYPE_PAYMENT 'P' /**< Transaction is a payment */
/**@}*/
-/***************************************************************
- * Transaction
- */
+/* --------------------------------------------------------------- */
+/* Transactions */
/** @name Transaction creation and editing */
-/**@{*/
+/** @{ */
/**
The xaccMallocTransaction() will malloc memory and initialize it.
Once created, it is usually unsafe to merely "free" this memory;
@@ -157,11 +212,11 @@
*/
guint gnc_book_count_transactions(QofBook *book);
-/**@}*/
+/** @} */
/** @name Transaction general getters/setters */
-/**@{*/
+/** @{ */
/** Sorts the splits in a transaction, putting the debits first,
* followed by the credits.
Index: qofbook.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofbook.h,v
retrieving revision 1.5.2.4
retrieving revision 1.5.2.5
diff -Lsrc/engine/qofbook.h -Lsrc/engine/qofbook.h -u -r1.5.2.4 -r1.5.2.5
--- src/engine/qofbook.h
+++ src/engine/qofbook.h
@@ -62,6 +62,7 @@
(c_type *) val; \
})
+/** \brief QofBook reference */
typedef struct _QofBook QofBook;
/** GList of QofBook */
Index: gnc-pricedb.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/gnc-pricedb.c,v
retrieving revision 1.48.4.5
retrieving revision 1.48.4.6
diff -Lsrc/engine/gnc-pricedb.c -Lsrc/engine/gnc-pricedb.c -u -r1.48.4.5 -r1.48.4.6
--- src/engine/gnc-pricedb.c
+++ src/engine/gnc-pricedb.c
@@ -553,13 +553,14 @@
gnc_pricedb_create(QofBook * book)
{
GNCPriceDB * result;
+ QofCollection *col;
g_return_val_if_fail (book, NULL);
/* There can only be one pricedb per book. So if one exits already,
* then use that. Warn user, they shouldn't be creating two ...
*/
- QofCollection *col = qof_book_get_collection (book, GNC_ID_PRICEDB);
+ col = qof_book_get_collection (book, GNC_ID_PRICEDB);
result = qof_collection_get_data (col);
if (result)
{
@@ -584,10 +585,11 @@
{
GList *price_list = (GList *) data;
GList *node;
+ GNCPrice *p;
for (node = price_list; node; node = node->next)
{
- GNCPrice *p = node->data;
+ p = node->data;
p->db = NULL;
}
@@ -2045,7 +2047,7 @@
interface_version: QOF_OBJECT_VERSION,
e_type: GNC_ID_PRICE,
type_label: "Price",
- create: NULL,
+ create: (gpointer)gnc_price_create,
book_begin: pricedb_book_begin,
book_end: pricedb_book_end,
is_dirty: pricedb_is_dirty,
@@ -2059,12 +2061,12 @@
gnc_pricedb_register (void)
{
static QofParam params[] = {
- { PRICE_COMMODITY, GNC_ID_COMMODITY, (QofAccessFunc)gnc_price_get_commodity, NULL },
- { PRICE_CURRENCY, GNC_ID_COMMODITY, (QofAccessFunc)gnc_price_get_currency, NULL },
- { PRICE_DATE, QOF_TYPE_DATE, (QofAccessFunc)gnc_price_get_time, NULL },
- { PRICE_SOURCE, QOF_TYPE_STRING, (QofAccessFunc)gnc_price_get_source, NULL },
- { PRICE_TYPE, QOF_TYPE_STRING, (QofAccessFunc)gnc_price_get_type, NULL },
- { PRICE_VALUE, QOF_TYPE_NUMERIC, (QofAccessFunc)gnc_price_get_value, NULL },
+ { PRICE_COMMODITY, GNC_ID_COMMODITY, (QofAccessFunc)gnc_price_get_commodity, (QofSetterFunc)gnc_price_set_commodity },
+ { PRICE_CURRENCY, GNC_ID_COMMODITY, (QofAccessFunc)gnc_price_get_currency, (QofSetterFunc)gnc_price_set_currency },
+ { PRICE_DATE, QOF_TYPE_DATE, (QofAccessFunc)gnc_price_get_time, (QofSetterFunc)gnc_price_set_time },
+ { PRICE_SOURCE, QOF_TYPE_STRING, (QofAccessFunc)gnc_price_get_source, (QofSetterFunc)gnc_price_set_source },
+ { PRICE_TYPE, QOF_TYPE_STRING, (QofAccessFunc)gnc_price_get_type, (QofSetterFunc)gnc_price_set_type },
+ { PRICE_VALUE, QOF_TYPE_NUMERIC, (QofAccessFunc)gnc_price_get_value, (QofSetterFunc)gnc_price_set_value },
{ NULL },
};
Index: Account.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/Account.h,v
retrieving revision 1.110.4.6
retrieving revision 1.110.4.7
diff -Lsrc/engine/Account.h -Lsrc/engine/Account.h -u -r1.110.4.6 -r1.110.4.7
--- src/engine/Account.h
+++ src/engine/Account.h
@@ -20,6 +20,22 @@
/** @addtogroup Engine
@{ */
/** @addtogroup Account
+ Splits are grouped into Accounts which are also known
+ as "Ledgers" in accounting practice. Each Account consists of a list of
+ Splits that debit that Account. To ensure consistency, if a Split points
+ to an Account, then the Account must point to the Split, and vice-versa.
+ A Split can belong to at most one Account. Besides merely containing a
+ list of Splits, the Account structure also give the Account a name, a
+ code number, description and notes fields, a key-value frame, a pointer
+ to the commodity that is used for all splits in this account. The
+ commodity can be the name of anything traded and tradable: a stock
+ (e.g. "IBM", "McDonald's"), a currency (e.g. "USD", "GBP"), or
+ anything added to the commodity table.
+
+ Accounts can be arranged in a hierarchical tree. The nodes of the tree
+ are called "Account Groups" (@pxref{Account Groups}). By accounting
+ convention, the value of an Account is equal to the value of all of its
+ Splits plus the value of all of its sub-Accounts.
@{ */
/** @file Account.h
@brief Account handling public routines
Index: Transaction.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/Transaction.c,v
retrieving revision 1.261.4.6
retrieving revision 1.261.4.7
diff -Lsrc/engine/Transaction.c -Lsrc/engine/Transaction.c -u -r1.261.4.6 -r1.261.4.7
--- src/engine/Transaction.c
+++ src/engine/Transaction.c
@@ -749,7 +749,7 @@
xaccSplitSetAmount (Split *s, gnc_numeric amt)
{
if(!s) return;
- ENTER ("split=%p old amt=%lld/%lld new amt=%lld/%lld", s,
+ ENTER ("(split=%p) old amt=%lld/%lld new amt=%lld/%lld", s,
s->amount.num, s->amount.denom, amt.num, amt.denom);
check_open (s->parent);
@@ -764,7 +764,7 @@
xaccSplitSetValue (Split *s, gnc_numeric amt)
{
if(!s) return;
- ENTER ("split=%p old val=%lld/%lld new val=%lld/%lld", s,
+ ENTER ("(split=%p) old val=%lld/%lld new val=%lld/%lld", s,
s->value.num, s->value.denom, amt.num, amt.denom);
check_open (s->parent);
@@ -1006,7 +1006,7 @@
if (!trans) return;
- ENTER ("addr=%p", trans);
+ ENTER ("(addr=%p)", trans);
if (((char *) 1) == trans->num)
{
PERR ("double-free %p", trans);
@@ -1044,7 +1044,7 @@
qof_instance_release (&trans->inst);
g_free(trans);
- LEAVE ("addr=%p", trans);
+ LEAVE ("(addr=%p)", trans);
}
/********************************************************************
@@ -1379,11 +1379,20 @@
gnc_numeric
xaccTransGetImbalance (const Transaction * trans)
{
- if (!trans)
- return gnc_numeric_zero ();
+ GList *node;
+ gnc_numeric imbal = gnc_numeric_zero();
+ if (!trans) return imbal;
+
+ ENTER("(trans=%p)", trans);
- return xaccSplitsComputeValue (trans->splits, NULL,
- trans->common_currency);
+ for (node=trans->splits; node; node=node->next)
+ {
+ Split *s = node->data;
+ imbal = gnc_numeric_add(imbal, xaccSplitGetValue(s),
+ GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT);
+ }
+ LEAVE("(trans=%p) imbal=%s", trans, gnc_num_dbg_to_string(imbal));
+ return imbal;
}
gnc_numeric
@@ -1402,7 +1411,7 @@
Account *a = xaccSplitGetAccount (s);
if (a == account)
total = gnc_numeric_add (total, xaccSplitGetValue (s),
- GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD);
+ GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT);
}
return total;
}
@@ -1552,6 +1561,9 @@
xaccTransCommitEdit (Transaction *trans)
{
QofBackend *be;
+
+ if (!trans) return;
+
QOF_COMMIT_EDIT_PART1 (&trans->inst);
/* We increment this for the duration of the call
@@ -1654,7 +1666,7 @@
trans->inst.editlevel--;
gen_event_trans (trans);
- LEAVE ("trans addr=%p\n", trans);
+ LEAVE ("(trans=%p)", trans);
}
/* Ughhh. The Rollback function is terribly complex, and, what's worse,
@@ -2835,8 +2847,9 @@
* handle some overflow and other error conditions by returning
* zero. But still print an error to let us know it happened.
*/
- if (gnc_numeric_check(price)) {
- PERR("Computing Shares Price Failed (%d): [ %lld / %lld ] / [ %lld / %lld ]",
+ if (gnc_numeric_check(price))
+ {
+ PERR("Computing share price failed (%d): [ %lld / %lld ] / [ %lld / %lld ]",
gnc_numeric_check(price), val.num, val.denom, amt.num, amt.denom);
return gnc_numeric_create(0,1);
}
@@ -3201,7 +3214,7 @@
interface_version: QOF_OBJECT_VERSION,
e_type: GNC_ID_SPLIT,
type_label: "Split",
- create: NULL,
+ create: (gpointer)xaccMallocSplit,
book_begin: NULL,
book_end: NULL,
is_dirty: NULL,
@@ -3252,13 +3265,13 @@
(QofAccessFunc)xaccSplitGetClearedBalance, NULL },
{ SPLIT_RECONCILED_BALANCE, QOF_TYPE_NUMERIC,
(QofAccessFunc)xaccSplitGetReconciledBalance, NULL },
- { SPLIT_MEMO, QOF_TYPE_STRING, (QofAccessFunc)xaccSplitGetMemo, NULL },
- { SPLIT_ACTION, QOF_TYPE_STRING, (QofAccessFunc)xaccSplitGetAction, NULL },
- { SPLIT_RECONCILE, QOF_TYPE_CHAR, (QofAccessFunc)xaccSplitGetReconcile, NULL },
- { SPLIT_AMOUNT, QOF_TYPE_NUMERIC, (QofAccessFunc)xaccSplitGetAmount, NULL },
+ { SPLIT_MEMO, QOF_TYPE_STRING, (QofAccessFunc)xaccSplitGetMemo, (QofSetterFunc)xaccSplitSetMemo },
+ { SPLIT_ACTION, QOF_TYPE_STRING, (QofAccessFunc)xaccSplitGetAction, (QofSetterFunc)xaccSplitSetAction },
+ { SPLIT_RECONCILE, QOF_TYPE_CHAR, (QofAccessFunc)xaccSplitGetReconcile, (QofSetterFunc)xaccSplitSetReconcile },
+ { SPLIT_AMOUNT, QOF_TYPE_NUMERIC, (QofAccessFunc)xaccSplitGetAmount, (QofSetterFunc)xaccSplitSetAmount },
{ SPLIT_SHARE_PRICE, QOF_TYPE_NUMERIC,
- (QofAccessFunc)xaccSplitGetSharePrice, NULL },
- { SPLIT_VALUE, QOF_TYPE_DEBCRED, (QofAccessFunc)xaccSplitGetValue, NULL },
+ (QofAccessFunc)xaccSplitGetSharePrice, (QofSetterFunc)xaccSplitSetSharePrice },
+ { SPLIT_VALUE, QOF_TYPE_DEBCRED, (QofAccessFunc)xaccSplitGetValue, (QofSetterFunc)xaccSplitSetValue },
{ SPLIT_TYPE, QOF_TYPE_STRING, (QofAccessFunc)xaccSplitGetType, NULL },
{ SPLIT_VOIDED_AMOUNT, QOF_TYPE_NUMERIC,
(QofAccessFunc)xaccSplitVoidFormerAmount, NULL },
@@ -3273,7 +3286,7 @@
{ SPLIT_ACCT_FULLNAME, SPLIT_ACCT_FULLNAME, no_op, NULL },
{ SPLIT_CORR_ACCT_NAME, SPLIT_CORR_ACCT_NAME, no_op, NULL },
{ SPLIT_CORR_ACCT_CODE, SPLIT_CORR_ACCT_CODE, no_op, NULL },
- { SPLIT_KVP, QOF_TYPE_KVP, (QofAccessFunc)xaccSplitGetSlots, NULL },
+ { SPLIT_KVP, QOF_TYPE_KVP, (QofAccessFunc)xaccSplitGetSlots, (QofSetterFunc)xaccSplitSetSlots_nc },
{ QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)xaccSplitGetBook, NULL },
{ QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_entity_get_guid, NULL },
{ NULL },
@@ -3297,7 +3310,7 @@
interface_version: QOF_OBJECT_VERSION,
e_type: GNC_ID_TRANS,
type_label: "Transaction",
- create: NULL,
+ create: (gpointer)xaccMallocTransaction,
book_begin: NULL,
book_end: NULL,
is_dirty: NULL,
@@ -3318,15 +3331,15 @@
gboolean xaccTransRegister (void)
{
static QofParam params[] = {
- { TRANS_NUM, QOF_TYPE_STRING, (QofAccessFunc)xaccTransGetNum,NULL },
- { TRANS_DESCRIPTION, QOF_TYPE_STRING, (QofAccessFunc)xaccTransGetDescription,NULL },
- { TRANS_DATE_ENTERED, QOF_TYPE_DATE, (QofAccessFunc)xaccTransRetDateEnteredTS,NULL },
- { TRANS_DATE_POSTED, QOF_TYPE_DATE, (QofAccessFunc)xaccTransRetDatePostedTS,NULL },
- { TRANS_DATE_DUE, QOF_TYPE_DATE, (QofAccessFunc)xaccTransRetDateDueTS,NULL },
+ { TRANS_NUM, QOF_TYPE_STRING, (QofAccessFunc)xaccTransGetNum, (QofSetterFunc)xaccTransSetNum },
+ { TRANS_DESCRIPTION, QOF_TYPE_STRING, (QofAccessFunc)xaccTransGetDescription, (QofSetterFunc)xaccTransSetDescription },
+ { TRANS_DATE_ENTERED, QOF_TYPE_DATE, (QofAccessFunc)xaccTransRetDateEnteredTS, (QofSetterFunc)xaccTransSetDateEnteredTS },
+ { TRANS_DATE_POSTED, QOF_TYPE_DATE, (QofAccessFunc)xaccTransRetDatePostedTS, (QofSetterFunc)xaccTransSetDatePostedTS },
+ { TRANS_DATE_DUE, QOF_TYPE_DATE, (QofAccessFunc)xaccTransRetDateDueTS, (QofSetterFunc)xaccTransSetDateDueTS },
{ TRANS_IMBALANCE, QOF_TYPE_NUMERIC, (QofAccessFunc)xaccTransGetImbalance,NULL },
- { TRANS_NOTES, QOF_TYPE_STRING, (QofAccessFunc)xaccTransGetNotes,NULL },
+ { TRANS_NOTES, QOF_TYPE_STRING, (QofAccessFunc)xaccTransGetNotes, (QofSetterFunc)xaccTransSetNotes },
{ TRANS_IS_BALANCED, QOF_TYPE_BOOLEAN, (QofAccessFunc)trans_is_balanced_p,NULL },
- { TRANS_TYPE, QOF_TYPE_CHAR, (QofAccessFunc)xaccTransGetTxnType,NULL },
+ { TRANS_TYPE, QOF_TYPE_CHAR, (QofAccessFunc)xaccTransGetTxnType, (QofSetterFunc)xaccTransSetTxnType },
{ TRANS_VOID_STATUS, QOF_TYPE_BOOLEAN, (QofAccessFunc)xaccTransGetVoidStatus,NULL },
{ TRANS_VOID_REASON, QOF_TYPE_STRING, (QofAccessFunc)xaccTransGetVoidReason,NULL },
{ TRANS_VOID_TIME, QOF_TYPE_DATE, (QofAccessFunc)xaccTransGetVoidTime,NULL },
Index: qofsession.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofsession.c,v
retrieving revision 1.2.4.6
retrieving revision 1.2.4.7
diff -Lsrc/engine/qofsession.c -Lsrc/engine/qofsession.c -u -r1.2.4.6 -r1.2.4.7
--- src/engine/qofsession.c
+++ src/engine/qofsession.c
@@ -476,6 +476,7 @@
qof_session_begin (QofSession *session, const char * book_id,
gboolean ignore_lock, gboolean create_if_nonexistent)
{
+ char * p;
if (!session) return;
ENTER (" sess=%p ignore_lock=%d, book-id=%s",
@@ -511,7 +512,7 @@
* "postgres://". Everything before the colon is the access
* method. Load the first backend found for that access method.
*/
- char * p = strchr (book_id, ':');
+ p = strchr (book_id, ':');
if (p)
{
char * access_method = g_strdup (book_id);
@@ -588,6 +589,11 @@
* id and a lock on the file. */
oldbooks = session->books;
+
+ /* XXX why are we creating a book here? I think the books
+ * need to be handled by the backend ... especially since
+ * the backend may need to load multiple books ... XXX. FIXME.
+ */
newbook = qof_book_new();
session->books = g_list_append (NULL, newbook);
PINFO ("new book=%p", newbook);
@@ -619,6 +625,11 @@
}
}
+ /* XXX if the load fails, then we try to restore the old set of books;
+ * however, we don't undo the session id (the URL). Thus if the
+ * user attempts to save after a failed load, they weill be trying to
+ * save to some bogus URL. This is wrong. XXX FIXME.
+ */
err = qof_session_get_error(session);
if ((err != ERR_BACKEND_NO_ERR) &&
(err != ERR_FILEIO_FILE_TOO_OLD) &&
Index: cap-gains.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/cap-gains.c,v
retrieving revision 1.13.4.2
retrieving revision 1.13.4.3
diff -Lsrc/engine/cap-gains.c -Lsrc/engine/cap-gains.c -u -r1.13.4.2 -r1.13.4.3
--- src/engine/cap-gains.c
+++ src/engine/cap-gains.c
@@ -27,15 +27,12 @@
* This file implements the various routines to automatically
* compute and handle Cap Gains/Losses resulting from trading
* activities. Some of these routines might have broader
- * applicability, for handling depreciation * & etc.
+ * applicability, for handling depreciation & etc.
*
- * This code is under development, and is 'alpha': many important
- * routines are missing, many existing routines are not called
- * from inside the engine as needed, and routines may be buggy.
- *
- * This code does not currently handle tax distinctions, e.g
- * the different tax treatment that short-term and long-term
- * cap gains have.
+ * This code is under development, and is 'beta': we think we're
+ * mostly done, and we've tested and "things work for us", but there
+ * may still be something missing, and there might still be some
+ * bugs.
*
* This code uses a 'gains dirty' flag: A 'dirty' flag on the source
* split indicates that the gains transaction needs to be recomputed.
@@ -192,7 +189,8 @@
lot = xaccAccountFindOpenLot (acc, sign, currency,
10000000LL * ((long long) LONG_MAX), earliest_pred);
- LEAVE ("found lot=%p %s", lot, gnc_lot_get_title (lot));
+ LEAVE ("found lot=%p %s baln=%s", lot, gnc_lot_get_title (lot),
+ gnc_num_dbg_to_string(gnc_lot_get_balance(lot)));
return lot;
}
@@ -488,7 +486,7 @@
val_a = gnc_numeric_mul (frac, val_tot,
gnc_numeric_denom(val_tot),
GNC_HOW_RND_ROUND| GNC_HOW_DENOM_EXACT);
-
+
val_b = gnc_numeric_sub_fixed (val_tot, val_a);
if (gnc_numeric_check(val_a))
{
@@ -608,7 +606,8 @@
*/
while (split)
{
- PINFO ("have split amount=%s", gnc_num_dbg_to_string (split->amount));
+ PINFO ("have split %p amount=%s", split,
+ gnc_num_dbg_to_string (split->amount));
split->gains |= GAINS_STATUS_VDIRTY;
lot = pcy->PolicyGetLot (pcy, split);
if (!lot)
@@ -674,6 +673,16 @@
/* Make sure the status flags and pointers are initialized */
if (GAINS_STATUS_UNKNOWN == split->gains) xaccSplitDetermineGainStatus(split);
+
+ /* Not possible to have gains if the transaction currency and
+ * account commodity are identical. */
+ if (gnc_commodity_equal (currency,
+ xaccAccountGetCommodity(split->acc)))
+ {
+ LEAVE ("Currency transfer, gains not possible, returning.");
+ return;
+ }
+
if (pcy->PolicyIsOpeningSplit (pcy, lot, split))
{
#if MOVE_THIS_TO_A_DATA_INTEGRITY_SCRUBBER
@@ -928,6 +937,7 @@
* just in case someone screwed with it! */
if (FALSE == gnc_commodity_equiv(currency,trans->common_currency))
{
+ PWARN ("Resetting the transaction currency!");
xaccTransSetCurrency (trans, currency);
}
}
@@ -955,7 +965,7 @@
xaccTransCommitEdit (trans);
}
- LEAVE ("(lot=%s)", kvp_frame_get_string (gnc_lot_get_slots (lot), "/title"));
+ LEAVE ("(lot=%s)", gnc_lot_get_title(lot));
}
/* ============================================================== */
Index: qofbackend-p.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofbackend-p.h,v
retrieving revision 1.2.4.1
retrieving revision 1.2.4.2
diff -Lsrc/engine/qofbackend-p.h -Lsrc/engine/qofbackend-p.h -u -r1.2.4.1 -r1.2.4.2
--- src/engine/qofbackend-p.h
+++ src/engine/qofbackend-p.h
@@ -72,9 +72,17 @@
* exist. This flag is used to implement the 'SaveAs' GUI, where
* the user requests to save data to a new backend.
*
- * The load() routine should return at least an account tree,
- * all currencies, pricedb, and any other data that needs to be
- * loaded at start time. It does not have to return any
+ * The load() routine should load the minimal set of application data
+ * needed for the application to be operable at initial startup.
+ * It is assumed that the application will perform a 'run_query()'
+ * to obtain any additional data that it needs. For file-based
+ * backends, it is acceptable for the backend to return all data
+ * at load time; for SQL-based backends, it is acceptable for the
+ * backend to return no data.
+ *
+ * Thus, for example, for GnuCash, the postrges backend returns
+ * the account tree, all currencies, and the pricedb, as these
+ * are needed at startup. It does not have to return any
* transactions whatsoever, as these are obtained at a later stage
* when a user opens a register, resulting in a query being sent to
* the backend.
Index: gnc-lot.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/gnc-lot.c,v
retrieving revision 1.14.4.4
retrieving revision 1.14.4.5
diff -Lsrc/engine/gnc-lot.c -Lsrc/engine/gnc-lot.c -u -r1.14.4.4 -r1.14.4.5
--- src/engine/gnc-lot.c
+++ src/engine/gnc-lot.c
@@ -247,7 +247,10 @@
Account * acc;
if (!lot || !split) return;
- ENTER ("(lot=%p, split=%p)", lot, split);
+ ENTER ("(lot=%p, split=%p) %s amt=%s val=%s", lot, split,
+ gnc_lot_get_title (lot),
+ gnc_num_dbg_to_string (split->amount),
+ gnc_num_dbg_to_string (split->value));
acc = xaccSplitGetAccount (split);
if (NULL == lot->account)
{
Index: kvp_frame.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/kvp_frame.c,v
retrieving revision 1.30.4.5
retrieving revision 1.30.4.6
diff -Lsrc/engine/kvp_frame.c -Lsrc/engine/kvp_frame.c -u -r1.30.4.5 -r1.30.4.6
--- src/engine/kvp_frame.c
+++ src/engine/kvp_frame.c
@@ -667,9 +667,11 @@
KvpValue *
kvp_frame_get_slot(const KvpFrame * frame, const char * slot)
{
+ KvpValue *v;
if (!frame) return NULL;
if (!frame->hash) return NULL; /* Error ... */
- return (KvpValue *)g_hash_table_lookup(frame->hash, slot);
+ v = g_hash_table_lookup(frame->hash, slot);
+ return v;
}
/* ============================================================ */
Index: qofid.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofid.c,v
retrieving revision 1.3.2.4
retrieving revision 1.3.2.5
diff -Lsrc/engine/qofid.c -Lsrc/engine/qofid.c -u -r1.3.2.4 -r1.3.2.5
--- src/engine/qofid.c
+++ src/engine/qofid.c
@@ -182,8 +182,9 @@
static void
qof_collection_remove_entity (QofEntity *ent)
{
+ QofCollection *col;
if (!ent) return;
- QofCollection *col = ent->collection;
+ col = ent->collection;
if (!col) return;
g_hash_table_remove (col->hash_of_entities, &ent->guid);
ent->collection = NULL;
Index: gnc-lot.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/gnc-lot.h,v
retrieving revision 1.8.4.5
retrieving revision 1.8.4.6
diff -Lsrc/engine/gnc-lot.h -Lsrc/engine/gnc-lot.h -u -r1.8.4.5 -r1.8.4.6
--- src/engine/gnc-lot.h
+++ src/engine/gnc-lot.h
@@ -31,7 +31,22 @@
*
* Lots are required to correctly implement invoices, inventory,
* depreciation and stock market investment gains. See the file
- * src/doc/lots.txt for implmentation overview.
+ * src/doc/lots.txt for a detailed implementation overview.
+ *
+ * A lot is "closed" when the number of items in the lot has gone to zero.
+ * It is very easy to compute the gains/losses for a closed lot: it is the
+ * sum-total of the values of the items put into/taken out of the lot.
+ * (Realized) Gains on still-open lots can be computed by pro-rating the
+ * purchase prices.
+ *
+ * Lots are nothing more than a collection or grouping of splits in an
+ * account. All of the splits in a lot must belong to the same account;
+ * there's no mix-n-match. Thus, in this sense, a lot belongs to an
+ * accunt as well.
+ *
+ * Lots have an implicit "opening date": the date of the earliest split in
+ * the lot. The "close date" is the date of the split that brought the lot
+ * item balance down to zero.
*
@{ */
Index: qof-be-utils.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qof-be-utils.h,v
retrieving revision 1.3.2.1
retrieving revision 1.3.2.2
diff -Lsrc/engine/qof-be-utils.h -Lsrc/engine/qof-be-utils.h -u -r1.3.2.1 -r1.3.2.2
--- src/engine/qof-be-utils.h
+++ src/engine/qof-be-utils.h
@@ -57,7 +57,7 @@
PERR ("unbalanced call - resetting (was %d)", (inst)->editlevel); \
(inst)->editlevel = 1; \
} \
- ENTER ("inst=%p", (inst)); \
+ ENTER ("(inst=%p)", (inst)); \
\
/* See if there's a backend. If there is, invoke it. */ \
be = qof_book_get_backend ((inst)->book); \
@@ -107,7 +107,7 @@
PERR ("unbalanced call - resetting (was %d)", (inst)->editlevel); \
(inst)->editlevel = 0; \
} \
- ENTER ("inst=%p, dirty=%d do-free=%d", \
+ ENTER ("(inst=%p) dirty=%d do-free=%d", \
(inst), (inst)->dirty, (inst)->do_free); \
}
Index: kvp-util.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/kvp-util.c,v
retrieving revision 1.4.4.4
retrieving revision 1.4.4.5
diff -Lsrc/engine/kvp-util.c -Lsrc/engine/kvp-util.c -u -r1.4.4.4 -r1.4.4.5
--- src/engine/kvp-util.c
+++ src/engine/kvp-util.c
@@ -165,7 +165,7 @@
static KvpFrame *
gnc_kvp_bag_get_first (KvpFrame *root, const char * path)
{
- KvpValue *arr;
+ KvpValue *arr, *va;
KvpValueType valtype;
GList *node;
@@ -182,7 +182,7 @@
node = kvp_value_get_glist(arr);
if (NULL == node) return NULL;
- KvpValue *va = node->data;
+ va = node->data;
return kvp_value_get_frame(va);
}
Index: gncEmployee.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/business/business-core/gncEmployee.c,v
retrieving revision 1.15.4.3
retrieving revision 1.15.4.4
diff -Lsrc/business/business-core/gncEmployee.c -Lsrc/business/business-core/gncEmployee.c -u -r1.15.4.3 -r1.15.4.4
--- src/business/business-core/gncEmployee.c
+++ src/business/business-core/gncEmployee.c
@@ -403,7 +403,7 @@
interface_version: QOF_OBJECT_VERSION,
e_type: _GNC_MOD_NAME,
type_label: "Employee",
- create: NULL,
+ create: (gpointer)gncEmployeeCreate,
book_begin: NULL,
book_end: NULL,
is_dirty: qof_collection_is_dirty,
@@ -416,10 +416,17 @@
gboolean gncEmployeeRegister (void)
{
static QofParam params[] = {
- { EMPLOYEE_ID, QOF_TYPE_STRING, (QofAccessFunc)gncEmployeeGetID, NULL },
- { EMPLOYEE_USERNAME, QOF_TYPE_STRING, (QofAccessFunc)gncEmployeeGetUsername, NULL },
+ { EMPLOYEE_ID, QOF_TYPE_STRING, (QofAccessFunc)gncEmployeeGetID, (QofSetterFunc)gncEmployeeSetID },
+ { EMPLOYEE_USERNAME, QOF_TYPE_STRING, (QofAccessFunc)gncEmployeeGetUsername,
+ (QofSetterFunc)gncEmployeeSetUsername },
+ { EMPLOYEE_LANGUAGE, QOF_TYPE_STRING, (QofAccessFunc)gncEmployeeGetLanguage,
+ (QofSetterFunc)gncEmployeeSetLanguage },
+ { EMPLOYEE_ACL, QOF_TYPE_STRING, (QofAccessFunc)gncEmployeeGetAcl, (QofSetterFunc)gncEmployeeSetAcl },
+ { EMPLOYEE_WORKDAY, QOF_TYPE_NUMERIC, (QofAccessFunc)gncEmployeeGetWorkday,
+ (QofSetterFunc)gncEmployeeSetWorkday },
+ { EMPLOYEE_RATE, QOF_TYPE_NUMERIC, (QofAccessFunc)gncEmployeeGetRate, (QofSetterFunc)gncEmployeeSetRate },
{ EMPLOYEE_ADDR, GNC_ADDRESS_MODULE_NAME, (QofAccessFunc)gncEmployeeGetAddr, NULL },
- { QOF_PARAM_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncEmployeeGetActive, NULL },
+ { QOF_PARAM_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncEmployeeGetActive, (QofSetterFunc)gncEmployeeSetActive },
{ QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
{ QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
{ NULL },
Index: gncBillTerm.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/business/business-core/gncBillTerm.h,v
retrieving revision 1.3.4.3
retrieving revision 1.3.4.4
diff -Lsrc/business/business-core/gncBillTerm.h -Lsrc/business/business-core/gncBillTerm.h -u -r1.3.4.3 -r1.3.4.4
--- src/business/business-core/gncBillTerm.h
+++ src/business/business-core/gncBillTerm.h
@@ -44,6 +44,18 @@
#define GNC_IS_BILLTERM(obj) (QOF_CHECK_TYPE((obj), GNC_ID_BILLTERM))
#define GNC_BILLTERM(obj) (QOF_CHECK_CAST((obj), GNC_ID_BILLTERM, GncBillTerm))
+/** @name BillTerm parameter names */
+/** @{ */
+#define GNC_BILLTERM_NAME "name"
+#define GNC_BILLTERM_DESC "description"
+#define GNC_BILLTERM_DUEDAYS "number of days due"
+#define GNC_BILLTERM_DISCDAYS "number of discounted days"
+#define GNC_BILLTERM_CUTOFF "cut off"
+#define GNC_BILLTERM_TYPE "bill type"
+#define GNC_BILLTERM_DISCOUNT "amount of discount"
+#define GNC_BILLTERM_REFCOUNT "reference count"
+/** @} */
+
/**
* How to interpret the amount.
* You can interpret it as a VALUE or a PERCENT.
Index: gncCustomer.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/business/business-core/gncCustomer.h,v
retrieving revision 1.13.4.4
retrieving revision 1.13.4.5
diff -Lsrc/business/business-core/gncCustomer.h -Lsrc/business/business-core/gncCustomer.h -u -r1.13.4.4 -r1.13.4.5
--- src/business/business-core/gncCustomer.h
+++ src/business/business-core/gncCustomer.h
@@ -74,6 +74,11 @@
void gncCustomerAddJob (GncCustomer *customer, GncJob *job);
void gncCustomerRemoveJob (GncCustomer *customer, GncJob *job);
+
+/** added for QOF standardisation */
+void gncCustomerSetTaxIncluded_q (GncCustomer *customer, gint taxincl);
+gint gncCustomerGetTaxIncluded_q (GncCustomer *cust);
+
/** @} */
/** @name Get Functions */
@@ -111,11 +116,14 @@
gboolean gncCustomerIsDirty (GncCustomer *customer);
int gncCustomerCompare (GncCustomer *a, GncCustomer *b);
-#define CUSTOMER_ID "id"
-#define CUSTOMER_NAME "name"
-#define CUSTOMER_ADDR "addr"
+#define CUSTOMER_ID "id"
+#define CUSTOMER_NAME "name"
+#define CUSTOMER_ADDR "addr"
#define CUSTOMER_SHIPADDR "shipaddr"
-
+#define CUSTOMER_NOTES "notes"
+#define CUSTOMER_DISCOUNT "amount of discount"
+#define CUSTOMER_CREDIT "amount of credit"
+#define CUSTOMER_TT_OVER "tax table override"
/** @deprecated functions, should be removed */
#define gncCustomerGetGUID(x) qof_instance_get_guid(QOF_INSTANCE(x))
#define gncCustomerRetGUID(x) (x ? *(qof_instance_get_guid(QOF_INSTANCE(x))) : *(guid_null()))
Index: gncInvoice.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/business/business-core/gncInvoice.c,v
retrieving revision 1.56.4.5
retrieving revision 1.56.4.6
diff -Lsrc/business/business-core/gncInvoice.c -Lsrc/business/business-core/gncInvoice.c -u -r1.56.4.5 -r1.56.4.6
--- src/business/business-core/gncInvoice.c
+++ src/business/business-core/gncInvoice.c
@@ -1363,7 +1363,7 @@
interface_version: QOF_OBJECT_VERSION,
e_type: _GNC_MOD_NAME,
type_label: "Invoice",
- create: NULL,
+ create: (gpointer)gncInvoiceCreate,
book_begin: NULL,
book_end: NULL,
is_dirty: qof_collection_is_dirty,
@@ -1400,22 +1400,22 @@
gboolean gncInvoiceRegister (void)
{
static QofParam params[] = {
- { INVOICE_ID, QOF_TYPE_STRING, (QofAccessFunc)gncInvoiceGetID, NULL },
- { INVOICE_OWNER, GNC_ID_OWNER, (QofAccessFunc)gncInvoiceGetOwner, NULL },
- { INVOICE_OPENED, QOF_TYPE_DATE, (QofAccessFunc)gncInvoiceGetDateOpened, NULL },
+ { INVOICE_ID, QOF_TYPE_STRING, (QofAccessFunc)gncInvoiceGetID, (QofSetterFunc)gncInvoiceSetID },
+ { INVOICE_OWNER, GNC_ID_OWNER, (QofAccessFunc)gncInvoiceGetOwner, (QofSetterFunc)gncInvoiceSetOwner },
+ { INVOICE_OPENED, QOF_TYPE_DATE, (QofAccessFunc)gncInvoiceGetDateOpened, (QofSetterFunc)gncInvoiceSetDateOpened },
{ INVOICE_DUE, QOF_TYPE_DATE, (QofAccessFunc)gncInvoiceGetDateDue, NULL },
- { INVOICE_POSTED, QOF_TYPE_DATE, (QofAccessFunc)gncInvoiceGetDatePosted, NULL },
+ { INVOICE_POSTED, QOF_TYPE_DATE, (QofAccessFunc)gncInvoiceGetDatePosted, (QofSetterFunc)gncInvoiceSetDatePosted },
{ INVOICE_IS_POSTED, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncInvoiceIsPosted, NULL },
{ INVOICE_IS_PAID, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncInvoiceIsPaid, NULL },
- { INVOICE_BILLINGID, QOF_TYPE_STRING, (QofAccessFunc)gncInvoiceGetBillingID, NULL },
- { INVOICE_NOTES, QOF_TYPE_STRING, (QofAccessFunc)gncInvoiceGetNotes, NULL },
+ { INVOICE_BILLINGID, QOF_TYPE_STRING, (QofAccessFunc)gncInvoiceGetBillingID, (QofSetterFunc)gncInvoiceSetBillingID },
+ { INVOICE_NOTES, QOF_TYPE_STRING, (QofAccessFunc)gncInvoiceGetNotes, (QofSetterFunc)gncInvoiceSetNotes },
{ INVOICE_ACC, GNC_ID_ACCOUNT, (QofAccessFunc)gncInvoiceGetPostedAcc, NULL },
{ INVOICE_POST_TXN, GNC_ID_TRANS, (QofAccessFunc)gncInvoiceGetPostedTxn, NULL },
{ INVOICE_POST_LOT, GNC_ID_LOT, (QofAccessFunc)gncInvoiceGetPostedLot, NULL },
{ INVOICE_TYPE, QOF_TYPE_STRING, (QofAccessFunc)gncInvoiceGetType, NULL },
- { INVOICE_TERMS, GNC_ID_BILLTERM, (QofAccessFunc)gncInvoiceGetTerms, NULL },
- { INVOICE_BILLTO, GNC_ID_OWNER, (QofAccessFunc)gncInvoiceGetBillTo, NULL },
- { QOF_PARAM_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncInvoiceGetActive, NULL },
+ { INVOICE_TERMS, GNC_ID_BILLTERM, (QofAccessFunc)gncInvoiceGetTerms, (QofSetterFunc)gncInvoiceSetTerms },
+ { INVOICE_BILLTO, GNC_ID_OWNER, (QofAccessFunc)gncInvoiceGetBillTo, (QofSetterFunc)gncInvoiceSetBillTo },
+ { QOF_PARAM_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncInvoiceGetActive, (QofSetterFunc)gncInvoiceSetActive },
{ QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
{ QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
{ NULL },
Index: gncCustomer.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/business/business-core/gncCustomer.c,v
retrieving revision 1.20.4.3
retrieving revision 1.20.4.4
diff -Lsrc/business/business-core/gncCustomer.c -Lsrc/business/business-core/gncCustomer.c -u -r1.20.4.3 -r1.20.4.4
--- src/business/business-core/gncCustomer.c
+++ src/business/business-core/gncCustomer.c
@@ -73,7 +73,7 @@
gboolean active;
GList * jobs;
- /* The following fields aer unique to 'customer' */
+ /* The following fields are unique to 'customer' */
gnc_numeric credit;
gnc_numeric discount;
GncAddress * shipaddr;
@@ -270,6 +270,13 @@
gncCustomerCommitEdit (cust);
}
+void gncCustomerSetTaxIncluded_q (GncCustomer *cust, gint taxincl)
+{
+ GncTaxIncluded g = taxincl;
+ if(!g) return;
+ gncCustomerSetTaxIncluded(cust, g);
+}
+
void gncCustomerSetTaxIncluded (GncCustomer *cust, GncTaxIncluded taxincl)
{
if (!cust) return;
@@ -444,6 +451,11 @@
return cust->terms;
}
+gint gncCustomerGetTaxIncluded_q (GncCustomer *cust)
+{
+ return (GncTaxIncluded)gncCustomerGetTaxIncluded(cust);
+}
+
GncTaxIncluded gncCustomerGetTaxIncluded (GncCustomer *cust)
{
if (!cust) return GNC_TAXINCLUDED_USEGLOBAL;
@@ -536,7 +548,7 @@
interface_version: QOF_OBJECT_VERSION,
e_type: _GNC_MOD_NAME,
type_label: "Customer",
- create: NULL,
+ create: (gpointer)gncCustomerCreate,
book_begin: NULL,
book_end: NULL,
is_dirty: qof_collection_is_dirty,
@@ -549,11 +561,18 @@
gboolean gncCustomerRegister (void)
{
static QofParam params[] = {
- { CUSTOMER_ID, QOF_TYPE_STRING, (QofAccessFunc)gncCustomerGetID, NULL },
- { CUSTOMER_NAME, QOF_TYPE_STRING, (QofAccessFunc)gncCustomerGetName, NULL },
+ { CUSTOMER_ID, QOF_TYPE_STRING, (QofAccessFunc)gncCustomerGetID, (QofSetterFunc)gncCustomerSetID },
+ { CUSTOMER_NAME, QOF_TYPE_STRING, (QofAccessFunc)gncCustomerGetName, (QofSetterFunc)gncCustomerSetName },
+ { CUSTOMER_NOTES, QOF_TYPE_STRING, (QofAccessFunc)gncCustomerGetNotes, (QofSetterFunc)gncCustomerSetNotes },
+ { CUSTOMER_DISCOUNT, QOF_TYPE_NUMERIC, (QofAccessFunc)gncCustomerGetDiscount,
+ (QofSetterFunc)gncCustomerSetDiscount },
+ { CUSTOMER_CREDIT, QOF_TYPE_NUMERIC, (QofAccessFunc)gncCustomerGetCredit,
+ (QofSetterFunc)gncCustomerSetCredit },
{ CUSTOMER_ADDR, GNC_ADDRESS_MODULE_NAME, (QofAccessFunc)gncCustomerGetAddr, NULL },
{ CUSTOMER_SHIPADDR, GNC_ADDRESS_MODULE_NAME, (QofAccessFunc)gncCustomerGetShipAddr, NULL },
- { QOF_PARAM_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncCustomerGetActive, NULL },
+ { CUSTOMER_TT_OVER, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncCustomerGetTaxTableOverride,
+ (QofSetterFunc)gncCustomerSetTaxTableOverride },
+ { QOF_PARAM_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncCustomerGetActive, (QofSetterFunc)gncCustomerSetActive },
{ QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
{ QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
{ NULL },
Index: gncEmployee.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/business/business-core/gncEmployee.h,v
retrieving revision 1.8.4.4
retrieving revision 1.8.4.5
diff -Lsrc/business/business-core/gncEmployee.h -Lsrc/business/business-core/gncEmployee.h -u -r1.8.4.4 -r1.8.4.5
--- src/business/business-core/gncEmployee.h
+++ src/business/business-core/gncEmployee.h
@@ -92,11 +92,13 @@
gboolean gncEmployeeIsDirty (GncEmployee *employee);
-
-
-#define EMPLOYEE_ID "id"
+#define EMPLOYEE_ID "id"
#define EMPLOYEE_USERNAME "username"
-#define EMPLOYEE_ADDR "addr"
+#define EMPLOYEE_ADDR "addr"
+#define EMPLOYEE_LANGUAGE "native language"
+#define EMPLOYEE_ACL "acl"
+#define EMPLOYEE_WORKDAY "workday"
+#define EMPLOYEE_RATE "rate"
/** deprecated routines */
#define gncEmployeeGetGUID(E) qof_entity_get_guid(QOF_ENTITY(E))
Index: gncVendor.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/business/business-core/gncVendor.c,v
retrieving revision 1.21.4.3
retrieving revision 1.21.4.4
diff -Lsrc/business/business-core/gncVendor.c -Lsrc/business/business-core/gncVendor.c -u -r1.21.4.3 -r1.21.4.4
--- src/business/business-core/gncVendor.c
+++ src/business/business-core/gncVendor.c
@@ -486,7 +486,7 @@
interface_version: QOF_OBJECT_VERSION,
e_type: _GNC_MOD_NAME,
type_label: "Vendor",
- create: NULL,
+ create: (gpointer)gncVendorCreate,
book_begin: NULL,
book_end: NULL,
is_dirty: qof_collection_is_dirty,
@@ -499,8 +499,8 @@
gboolean gncVendorRegister (void)
{
static QofParam params[] = {
- { VENDOR_ID, QOF_TYPE_STRING, (QofAccessFunc)gncVendorGetID, NULL },
- { VENDOR_NAME, QOF_TYPE_STRING, (QofAccessFunc)gncVendorGetName, NULL },
+ { VENDOR_ID, QOF_TYPE_STRING, (QofAccessFunc)gncVendorGetID, (QofSetterFunc)gncVendorSetID },
+ { VENDOR_NAME, QOF_TYPE_STRING, (QofAccessFunc)gncVendorGetName, (QofSetterFunc)gncVendorSetName },
{ VENDOR_ADDR, GNC_ADDRESS_MODULE_NAME, (QofAccessFunc)gncVendorGetAddr, NULL },
{ QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
{ QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
Index: gncJob.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/business/business-core/gncJob.c,v
retrieving revision 1.18.4.4
retrieving revision 1.18.4.5
diff -Lsrc/business/business-core/gncJob.c -Lsrc/business/business-core/gncJob.c -u -r1.18.4.4 -r1.18.4.5
--- src/business/business-core/gncJob.c
+++ src/business/business-core/gncJob.c
@@ -353,7 +353,7 @@
interface_version: QOF_OBJECT_VERSION,
e_type: _GNC_MOD_NAME,
type_label: "Job",
- create: NULL,
+ create: (gpointer)gncJobCreate,
book_begin: NULL,
book_end: NULL,
is_dirty: qof_collection_is_dirty,
@@ -366,11 +366,11 @@
gboolean gncJobRegister (void)
{
static QofParam params[] = {
- { JOB_ID, QOF_TYPE_STRING, (QofAccessFunc)gncJobGetID, NULL },
- { JOB_NAME, QOF_TYPE_STRING, (QofAccessFunc)gncJobGetName, NULL },
- { JOB_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncJobGetActive, NULL },
- { JOB_REFERENCE, QOF_TYPE_STRING, (QofAccessFunc)gncJobGetReference, NULL },
- { JOB_OWNER, GNC_ID_OWNER, (QofAccessFunc)gncJobGetOwner, NULL },
+ { JOB_ID, QOF_TYPE_STRING, (QofAccessFunc)gncJobGetID, (QofSetterFunc)gncJobSetID },
+ { JOB_NAME, QOF_TYPE_STRING, (QofAccessFunc)gncJobGetName, (QofSetterFunc)gncJobSetName },
+ { JOB_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncJobGetActive, (QofSetterFunc)gncJobSetActive },
+ { JOB_REFERENCE, QOF_TYPE_STRING, (QofAccessFunc)gncJobGetReference, (QofSetterFunc)gncJobSetReference },
+ { JOB_OWNER, GNC_ID_OWNER, (QofAccessFunc)gncJobGetOwner, (QofSetterFunc)gncJobSetOwner },
{ QOF_PARAM_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncJobGetActive, NULL },
{ QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
{ QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
Index: gncBillTerm.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/business/business-core/gncBillTerm.c,v
retrieving revision 1.6.4.3
retrieving revision 1.6.4.4
diff -Lsrc/business/business-core/gncBillTerm.c -Lsrc/business/business-core/gncBillTerm.c -u -r1.6.4.3 -r1.6.4.4
--- src/business/business-core/gncBillTerm.c
+++ src/business/business-core/gncBillTerm.c
@@ -691,6 +691,22 @@
gboolean gncBillTermRegister (void)
{
static QofParam params[] = {
+ { GNC_BILLTERM_NAME, QOF_TYPE_STRING, (QofAccessFunc)gncBillTermGetName,
+ (QofSetterFunc)gncBillTermSetName },
+ { GNC_BILLTERM_DESC, QOF_TYPE_STRING, (QofAccessFunc)gncBillTermGetDescription,
+ (QofSetterFunc)gncBillTermSetDescription },
+ { GNC_BILLTERM_TYPE, QOF_TYPE_INT32, (QofAccessFunc)gncBillTermGetType,
+ (QofSetterFunc)gncBillTermSetType },
+ { GNC_BILLTERM_DUEDAYS, QOF_TYPE_INT32, (QofAccessFunc)gncBillTermGetDueDays,
+ (QofSetterFunc)gncBillTermSetDueDays },
+ { GNC_BILLTERM_DISCDAYS, QOF_TYPE_INT32, (QofAccessFunc)gncBillTermGetDiscountDays,
+ (QofSetterFunc)gncBillTermSetDiscountDays },
+ { GNC_BILLTERM_DISCOUNT, QOF_TYPE_NUMERIC, (QofAccessFunc)gncBillTermGetDiscount,
+ (QofSetterFunc)gncBillTermSetDiscount },
+ { GNC_BILLTERM_CUTOFF, QOF_TYPE_INT32, (QofAccessFunc)gncBillTermGetCutoff,
+ (QofSetterFunc)gncBillTermSetCutoff },
+ { GNC_BILLTERM_REFCOUNT, QOF_TYPE_INT64, (QofAccessFunc)gncBillTermGetRefcount, NULL },
+ { QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
{ QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
{ QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
{ NULL },
Index: gncEntry.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/business/business-core/gncEntry.c,v
retrieving revision 1.32.4.3
retrieving revision 1.32.4.4
diff -Lsrc/business/business-core/gncEntry.c -Lsrc/business/business-core/gncEntry.c -u -r1.32.4.3 -r1.32.4.4
--- src/business/business-core/gncEntry.c
+++ src/business/business-core/gncEntry.c
@@ -1169,7 +1169,7 @@
interface_version: QOF_OBJECT_VERSION,
e_type: _GNC_MOD_NAME,
type_label: "Order/Invoice/Bill Entry",
- create: NULL,
+ create: (gpointer)gncEntryCreate,
book_begin: NULL,
book_end: NULL,
is_dirty: qof_collection_is_dirty,
@@ -1182,18 +1182,18 @@
gboolean gncEntryRegister (void)
{
static QofParam params[] = {
- { ENTRY_DATE, QOF_TYPE_DATE, (QofAccessFunc)gncEntryGetDate, NULL },
- { ENTRY_DATE_ENTERED, QOF_TYPE_DATE, (QofAccessFunc)gncEntryGetDateEntered, NULL },
- { ENTRY_DESC, QOF_TYPE_STRING, (QofAccessFunc)gncEntryGetDescription, NULL },
- { ENTRY_ACTION, QOF_TYPE_STRING, (QofAccessFunc)gncEntryGetAction, NULL },
- { ENTRY_NOTES, QOF_TYPE_STRING, (QofAccessFunc)gncEntryGetNotes, NULL },
- { ENTRY_QTY, QOF_TYPE_NUMERIC, (QofAccessFunc)gncEntryGetQuantity, NULL },
- { ENTRY_IPRICE, QOF_TYPE_NUMERIC, (QofAccessFunc)gncEntryGetInvPrice, NULL },
- { ENTRY_BPRICE, QOF_TYPE_NUMERIC, (QofAccessFunc)gncEntryGetBillPrice, NULL },
+ { ENTRY_DATE, QOF_TYPE_DATE, (QofAccessFunc)gncEntryGetDate, (QofSetterFunc)gncEntrySetDate },
+ { ENTRY_DATE_ENTERED, QOF_TYPE_DATE, (QofAccessFunc)gncEntryGetDateEntered, (QofSetterFunc)gncEntrySetDateEntered },
+ { ENTRY_DESC, QOF_TYPE_STRING, (QofAccessFunc)gncEntryGetDescription, (QofSetterFunc)gncEntrySetDescription },
+ { ENTRY_ACTION, QOF_TYPE_STRING, (QofAccessFunc)gncEntryGetAction, (QofSetterFunc)gncEntrySetAction },
+ { ENTRY_NOTES, QOF_TYPE_STRING, (QofAccessFunc)gncEntryGetNotes, (QofSetterFunc)gncEntrySetNotes },
+ { ENTRY_QTY, QOF_TYPE_NUMERIC, (QofAccessFunc)gncEntryGetQuantity, (QofSetterFunc)gncEntrySetQuantity },
+ { ENTRY_IPRICE, QOF_TYPE_NUMERIC, (QofAccessFunc)gncEntryGetInvPrice, (QofSetterFunc)gncEntrySetInvPrice },
+ { ENTRY_BPRICE, QOF_TYPE_NUMERIC, (QofAccessFunc)gncEntryGetBillPrice, (QofSetterFunc)gncEntrySetBillPrice },
{ ENTRY_INVOICE, GNC_ID_INVOICE, (QofAccessFunc)gncEntryGetInvoice, NULL },
{ ENTRY_BILL, GNC_ID_INVOICE, (QofAccessFunc)gncEntryGetBill, NULL },
- { ENTRY_BILLABLE, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncEntryGetBillable, NULL },
- { ENTRY_BILLTO, GNC_ID_OWNER, (QofAccessFunc)gncEntryGetBillTo, NULL },
+ { ENTRY_BILLABLE, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncEntryGetBillable, (QofSetterFunc)gncEntrySetBillable },
+ { ENTRY_BILLTO, GNC_ID_OWNER, (QofAccessFunc)gncEntryGetBillTo, (QofSetterFunc)gncEntrySetBillTo },
{ ENTRY_ORDER, GNC_ID_ORDER, (QofAccessFunc)gncEntryGetOrder, NULL },
{ QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
{ QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
Index: gncAddress.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/business/business-core/gncAddress.c,v
retrieving revision 1.4.4.2
retrieving revision 1.4.4.3
diff -Lsrc/business/business-core/gncAddress.c -Lsrc/business/business-core/gncAddress.c -u -r1.4.4.2 -r1.4.4.3
--- src/business/business-core/gncAddress.c
+++ src/business/business-core/gncAddress.c
@@ -285,10 +285,10 @@
{
static QofParam params[] = {
- { ADDRESS_NAME, QOF_TYPE_STRING, (QofAccessFunc)gncAddressGetName, NULL },
- { ADDRESS_PHONE, QOF_TYPE_STRING, (QofAccessFunc)gncAddressGetPhone, NULL },
- { ADDRESS_FAX, QOF_TYPE_STRING, (QofAccessFunc)gncAddressGetFax, NULL },
- { ADDRESS_EMAIL, QOF_TYPE_STRING, (QofAccessFunc)gncAddressGetEmail, NULL },
+ { ADDRESS_NAME, QOF_TYPE_STRING, (QofAccessFunc)gncAddressGetName, (QofSetterFunc)gncAddressSetName },
+ { ADDRESS_PHONE, QOF_TYPE_STRING, (QofAccessFunc)gncAddressGetPhone, (QofSetterFunc)gncAddressSetPhone },
+ { ADDRESS_FAX, QOF_TYPE_STRING, (QofAccessFunc)gncAddressGetFax, (QofSetterFunc)gncAddressSetFax },
+ { ADDRESS_EMAIL, QOF_TYPE_STRING, (QofAccessFunc)gncAddressGetEmail, (QofSetterFunc)gncAddressSetEmail },
{ NULL },
};
Index: gncTaxTable.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/business/business-core/gncTaxTable.c,v
retrieving revision 1.9.4.3
retrieving revision 1.9.4.4
diff -Lsrc/business/business-core/gncTaxTable.c -Lsrc/business/business-core/gncTaxTable.c -u -r1.9.4.3 -r1.9.4.4
--- src/business/business-core/gncTaxTable.c
+++ src/business/business-core/gncTaxTable.c
@@ -464,6 +464,12 @@
mod_table (entry->table);
}
}
+void gncTaxTableEntrySetType_q (GncTaxTableEntry *entry, gint type)
+{
+ GncAmountType q = type;
+ if(!q) return;
+ gncTaxTableEntrySetType(entry,q);
+}
void gncTaxTableEntrySetType (GncTaxTableEntry *entry, GncAmountType type)
{
@@ -663,6 +669,11 @@
return entry->account;
}
+gint gncTaxTableEntryGetType_q (GncTaxTableEntry *entry)
+{
+ return (GncAmountType)gncTaxTableEntryGetType(entry);
+}
+
GncAmountType gncTaxTableEntryGetType (GncTaxTableEntry *entry)
{
if (!entry) return 0;
@@ -799,7 +810,7 @@
interface_version: QOF_OBJECT_VERSION,
e_type: _GNC_MOD_NAME,
type_label: "Tax Table",
- create: NULL,
+ create: (gpointer)gncTaxTableCreate,
book_begin: _gncTaxTableCreate,
book_end: _gncTaxTableDestroy,
is_dirty: qof_collection_is_dirty,
@@ -812,6 +823,8 @@
gboolean gncTaxTableRegister (void)
{
static QofParam params[] = {
+ { GNC_TT_NAME, QOF_TYPE_STRING, (QofAccessFunc)gncTaxTableGetName, (QofSetterFunc)gncTaxTableSetName },
+ { GNC_TT_REFCOUNT, QOF_TYPE_INT64, (QofAccessFunc)gncTaxTableGetRefcount, NULL },
{ QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
{ QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
{ NULL },
@@ -821,3 +834,7 @@
return qof_object_register (&gncTaxTableDesc);
}
+
+/* need a QOF tax table entry object */
+//gncTaxTableEntrySetType_q int32
+//gint gncTaxTableEntryGetType_q (GncTaxTableEntry *entry);
Index: gncOrder.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/business/business-core/gncOrder.c,v
retrieving revision 1.23.4.3
retrieving revision 1.23.4.4
diff -Lsrc/business/business-core/gncOrder.c -Lsrc/business/business-core/gncOrder.c -u -r1.23.4.3 -r1.23.4.4
--- src/business/business-core/gncOrder.c
+++ src/business/business-core/gncOrder.c
@@ -438,14 +438,14 @@
gboolean gncOrderRegister (void)
{
static QofParam params[] = {
- { ORDER_ID, QOF_TYPE_STRING, (QofAccessFunc)gncOrderGetID, NULL },
- { ORDER_REFERENCE, QOF_TYPE_STRING, (QofAccessFunc)gncOrderGetReference, NULL },
- { ORDER_OWNER, GNC_ID_OWNER, (QofAccessFunc)gncOrderGetOwner, NULL },
- { ORDER_OPENED, QOF_TYPE_DATE, (QofAccessFunc)gncOrderGetDateOpened, NULL },
+ { ORDER_ID, QOF_TYPE_STRING, (QofAccessFunc)gncOrderGetID, (QofSetterFunc)gncOrderSetID },
+ { ORDER_REFERENCE, QOF_TYPE_STRING, (QofAccessFunc)gncOrderGetReference, (QofSetterFunc)gncOrderSetReference },
+ { ORDER_OWNER, GNC_ID_OWNER, (QofAccessFunc)gncOrderGetOwner, (QofSetterFunc)gncOrderSetOwner },
+ { ORDER_OPENED, QOF_TYPE_DATE, (QofAccessFunc)gncOrderGetDateOpened, (QofSetterFunc)gncOrderSetDateOpened },
{ ORDER_IS_CLOSED, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncOrderIsClosed, NULL },
- { ORDER_CLOSED, QOF_TYPE_DATE, (QofAccessFunc)gncOrderGetDateClosed, NULL },
- { ORDER_NOTES, QOF_TYPE_STRING, (QofAccessFunc)gncOrderGetNotes, NULL },
- { QOF_PARAM_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncOrderGetActive, NULL },
+ { ORDER_CLOSED, QOF_TYPE_DATE, (QofAccessFunc)gncOrderGetDateClosed, (QofSetterFunc)gncOrderSetDateClosed },
+ { ORDER_NOTES, QOF_TYPE_STRING, (QofAccessFunc)gncOrderGetNotes, (QofSetterFunc)gncOrderSetNotes },
+ { QOF_PARAM_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncOrderGetActive, (QofSetterFunc)gncOrderSetActive },
{ QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
{ QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
{ NULL },
Index: gncTaxTable.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/business/business-core/gncTaxTable.h,v
retrieving revision 1.7.4.4
retrieving revision 1.7.4.5
diff -Lsrc/business/business-core/gncTaxTable.h -Lsrc/business/business-core/gncTaxTable.h -u -r1.7.4.4 -r1.7.4.5
--- src/business/business-core/gncTaxTable.h
+++ src/business/business-core/gncTaxTable.h
@@ -52,15 +52,15 @@
* You can interpret it as a VALUE or a PERCENT.
*/
typedef enum {
- GNC_AMT_TYPE_VALUE = 1,
- GNC_AMT_TYPE_PERCENT
+ GNC_AMT_TYPE_VALUE = 1, /**< tax is a number */
+ GNC_AMT_TYPE_PERCENT /**< tax is a percentage */
} GncAmountType;
/** How to interpret the TaxIncluded */
typedef enum {
- GNC_TAXINCLUDED_YES = 1,
- GNC_TAXINCLUDED_NO,
- GNC_TAXINCLUDED_USEGLOBAL,
+ GNC_TAXINCLUDED_YES = 1, /**< tax is included */
+ GNC_TAXINCLUDED_NO, /**< tax is not included */
+ GNC_TAXINCLUDED_USEGLOBAL, /**< use the global setting */
} GncTaxIncluded;
const char * gncAmountTypeToString (GncAmountType type);
@@ -91,6 +91,11 @@
void gncTaxTableChanged (GncTaxTable *table);
void gncTaxTableBeginEdit (GncTaxTable *table);
void gncTaxTableCommitEdit (GncTaxTable *table);
+
+/** added for later QOF standardisation */
+gint gncTaxTableEntryGetType_q (GncTaxTableEntry *entry);
+void gncTaxTableEntrySetType_q (GncTaxTableEntry *entry, gint type);
+
/** @} */
/** @name Get Functions */
@@ -147,6 +152,10 @@
/** Destroy a list of accountvalues */
void gncAccountValueDestroy (GList *list);
+/** QOF parameter definitions */
+#define GNC_TT_NAME "tax table name"
+#define GNC_TT_REFCOUNT "reference count"
+
/** @deprecated routine */
#define gncTaxTableGetGUID(x) qof_instance_get_guid(QOF_INSTANCE(x))
#define gncTaxTableRetGUID(x) (x ? *(qof_instance_get_guid(QOF_INSTANCE(x))) : *(guid_null()))
Index: test-numeric.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/test/test-numeric.c,v
retrieving revision 1.18.2.1
retrieving revision 1.18.2.2
diff -Lsrc/engine/test/test-numeric.c -Lsrc/engine/test/test-numeric.c -u -r1.18.2.1 -r1.18.2.2
--- src/engine/test/test-numeric.c
+++ src/engine/test/test-numeric.c
@@ -112,19 +112,22 @@
static void
check_reduce (void)
{
+ gnc_numeric one, rone;
+ gnc_numeric four, rfour;
+ gnc_numeric val, rval;
/* Check common factor elimination (needed for equality checks) */
- gnc_numeric one = gnc_numeric_create (1,1);
- gnc_numeric rone = gnc_numeric_create (1000000,1000000);
+ one = gnc_numeric_create (1,1);
+ rone = gnc_numeric_create (1000000,1000000);
rone = gnc_numeric_reduce (rone);
do_test (gnc_numeric_eq(one, rone), "reduce to one");
- gnc_numeric four = gnc_numeric_create (4,1);
- gnc_numeric rfour = gnc_numeric_create (480,120);
+ four = gnc_numeric_create (4,1);
+ rfour = gnc_numeric_create (480,120);
rfour = gnc_numeric_reduce (rfour);
do_test (gnc_numeric_eq(four, rfour), "reduce to four");
- gnc_numeric val = gnc_numeric_create(10023234LL, 334216654LL);
- gnc_numeric rval = gnc_numeric_reduce (val);
+ val = gnc_numeric_create(10023234LL, 334216654LL);
+ rval = gnc_numeric_reduce (val);
check_unary_op (gnc_numeric_eq,
gnc_numeric_create (5011617,167108327),
rval,
@@ -150,14 +153,20 @@
static void
check_equality_operator (void)
{
+ int i, m;
+ gint deno, mult, numer;
+ gint64 f;
+ gnc_numeric big, rbig;
+ gnc_numeric val, mval;
+ gnc_numeric bval, rval;
/* Check equality operator for some large numer/denom values */
- gint64 numer = 1<<30;
+ numer = 1<<30;
numer <<= 30; /* we don't trust cpp to compute 1<<60 correctly */
- gint64 deno = 1<<30;
+ deno = 1<<30;
deno <<= 20;
- gnc_numeric rbig = gnc_numeric_create (numer, deno);
+ rbig = gnc_numeric_create (numer, deno);
- gnc_numeric big = gnc_numeric_create (1<<10,1);
+ big = gnc_numeric_create (1<<10,1);
do_test (gnc_numeric_equal(big, rbig), "equal to billion");
big = gnc_numeric_create (1<<20,1<<10);
@@ -183,20 +192,19 @@
big = gnc_numeric_create (numer, 1<<20);
do_test (gnc_numeric_equal(big, rbig), "equal to 1<<50/1<<20");
- int i;
/* We assume RAND_MAX is less that 1<<32 */
for (i=0; i<NREPS; i++)
{
- gint64 deno = rand() / 2;
- gint64 mult = rand() / 2;
- gint64 numer = rand() / 2;
+ deno = rand() / 2;
+ mult = rand() / 2;
+ numer = rand() / 2;
- gnc_numeric val = gnc_numeric_create (numer, deno);
- gnc_numeric mval = gnc_numeric_create (numer*mult, deno*mult);
+ val = gnc_numeric_create (numer, deno);
+ mval = gnc_numeric_create (numer*mult, deno*mult);
/* The reduced version should be equivalent */
- gnc_numeric bval = gnc_numeric_reduce (val);
- gnc_numeric rval = gnc_numeric_reduce (mval);
+ bval = gnc_numeric_reduce (val);
+ rval = gnc_numeric_reduce (mval);
check_unary_op (gnc_numeric_eq,
bval, rval, mval, "expected %s = %s = reduce(%s)");
@@ -209,8 +217,8 @@
* might creep in. */
mval.denom >>= 1;
mval.num >>= 1;
- int m=0;
- gint64 f = mval.denom;
+ m=0;
+ f = mval.denom;
while (f%2 == 0)
{
f >>= 1;
@@ -297,6 +305,7 @@
static void
check_double (void)
{
+ double flo;
gnc_numeric val = gnc_numeric_create (0,1);
check_unary_op (gnc_numeric_eq,
@@ -330,7 +339,7 @@
GNC_HOW_RND_ROUND),
val, "expected %s = %s double 6 figs");
- double flo = gnc_numeric_to_double(gnc_numeric_create(7, 16));
+ flo = gnc_numeric_to_double(gnc_numeric_create(7, 16));
do_test ((0.4375 == flo), "float pt conversion");
}
@@ -359,8 +368,14 @@
static void
check_add_subtract (void)
{
- gnc_numeric a = gnc_numeric_create(2, 6);
- gnc_numeric b = gnc_numeric_create(1, 4);
+ int i;
+ gnc_numeric a, b, c, d, z;
+#if CHECK_ERRORS_TOO
+ gnc_numeric c;
+#endif
+
+ a = gnc_numeric_create(2, 6);
+ b = gnc_numeric_create(1, 4);
/* Well, actually 14/24 would be acceptable/better in this case */
check_binary_op (gnc_numeric_create(7,12),
@@ -402,9 +417,9 @@
/* ------------------------------------------------------------ */
/* This test has failed before */
- gnc_numeric c = gnc_numeric_neg (a);
- gnc_numeric d = gnc_numeric_neg (b);
- gnc_numeric z = gnc_numeric_zero();
+ c = gnc_numeric_neg (a);
+ d = gnc_numeric_neg (b);
+ z = gnc_numeric_zero();
check_binary_op (c, gnc_numeric_add_fixed(z,c),
z, c, "expected %s got %s = %s + %s for add fixed");
@@ -455,7 +470,6 @@
/* ------------------------------------------------------------ */
#if CHECK_ERRORS_TOO
- gnc_numeric c;
c = gnc_numeric_add_with_error(a, b, 100, GNC_HOW_RND_ROUND, &err);
printf("add 100ths/error : %s + %s = %s + (error) %s\n\n",
gnc_numeric_print(a), gnc_numeric_print(b),
@@ -472,7 +486,6 @@
/* ------------------------------------------------------------ */
/* Add and subtract some random numbers */
- int i;
for (i=0; i<NREPS; i++)
{
gnc_numeric e;
@@ -509,7 +522,11 @@
static void
check_mult_div (void)
{
+ int i, j;
+ gint64 v;
gnc_numeric c, d;
+ gnc_numeric amt_a, amt_tot, frac, val_tot, val_a;
+
gnc_numeric a = gnc_numeric_create(2, 6);
gnc_numeric b = gnc_numeric_create(1, 4);
@@ -556,7 +573,7 @@
/* Check for math with 2^63 < num*num < 2^64 which previously failed
* see http://bugzilla.gnome.org/show_bug.cgi?id=144980
*/
- gint64 v = 1000000;
+ v = 1000000;
a = gnc_numeric_create(1*v, v);
b = gnc_numeric_create(10000000*v, v);
@@ -567,7 +584,6 @@
/* Multiply some random numbers. This test presumes that
* RAND_MAX is approx 2^32
*/
- int i;
for (i=0; i<NREPS; i++)
{
gint64 deno = 1;
@@ -588,7 +604,6 @@
a, b, "expected %s got %s = %s * %s for mult exact");
/* Force 128-bit math to come into play */
- int j;
for (j=1; j<31; j++)
{
a = gnc_numeric_create(na << j, 1<<j);
@@ -673,9 +688,9 @@
c, d, "expected %s got %s = %s / %s for div round");
/* A simple irreducible ratio, involving negative numbers */
- gnc_numeric amt_a = gnc_numeric_create (-6005287905LL, 40595);
- gnc_numeric amt_tot = gnc_numeric_create (-8744187958LL, 40595);
- gnc_numeric frac = gnc_numeric_div (amt_a, amt_tot,
+ amt_a = gnc_numeric_create (-6005287905LL, 40595);
+ amt_tot = gnc_numeric_create (-8744187958LL, 40595);
+ frac = gnc_numeric_div (amt_a, amt_tot,
GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE);
check_binary_op (gnc_numeric_create(6005287905LL, 8744187958LL),
@@ -683,8 +698,8 @@
"expected %s got %s = %s / %s for div reduce");
/* Another overflow-prone condition */
- gnc_numeric val_tot = gnc_numeric_create (-4280656418LL, 19873);
- gnc_numeric val_a = gnc_numeric_mul (frac, val_tot,
+ val_tot = gnc_numeric_create (-4280656418LL, 19873);
+ val_a = gnc_numeric_mul (frac, val_tot,
gnc_numeric_denom(val_tot),
GNC_HOW_RND_ROUND| GNC_HOW_DENOM_EXACT);
check_binary_op (gnc_numeric_create(-2939846940LL, 19873),
@@ -699,6 +714,19 @@
check_binary_op (gnc_numeric_create(562854125307LL, 100),
val_a, val_tot, frac,
"expected %s got %s = %s * %s for mult round");
+
+ /* Yet another bug from bugzilla ... */
+ a = gnc_numeric_create (40066447153986554LL, 4518);
+ b = gnc_numeric_create (26703286457229LL, 3192);
+ frac = gnc_numeric_div(a, b,
+ GNC_DENOM_AUTO,
+ GNC_HOW_DENOM_SIGFIGS(6) |
+ GNC_HOW_RND_ROUND);
+
+ check_binary_op (gnc_numeric_create(106007, 100),
+ frac, a, b,
+ "expected %s got %s = %s / %s for mult sigfigs");
+
}
/* ======================================================= */
Index: test-lots.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/test/test-lots.c,v
retrieving revision 1.3.4.2
retrieving revision 1.3.4.3
diff -Lsrc/engine/test/test-lots.c -Lsrc/engine/test/test-lots.c -u -r1.3.4.2 -r1.3.4.3
--- src/engine/test/test-lots.c
+++ src/engine/test/test-lots.c
@@ -59,16 +59,18 @@
* automatically fail! */
g_log_set_always_fatal( G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING );
- set_success_print (TRUE);
+ //set_success_print (TRUE);
do_test((NULL!=gnc_module_load("gnucash/engine", 0)), "load engine");
- /* set the rng to a known starting point */
+ /* Set up a reproducible test-case */
srand(0);
/* Iterate the test a number of times */
- for (i=0; i< 20; i++)
+ for (i=0; i< 100; i++)
+ {
run_test ();
+ }
print_test_results();
exit(get_rv());
Index: test-transaction-reversal.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/test/test-transaction-reversal.c,v
retrieving revision 1.3.4.1
retrieving revision 1.3.4.2
diff -Lsrc/engine/test/test-transaction-reversal.c -Lsrc/engine/test/test-transaction-reversal.c -u -r1.3.4.1 -r1.3.4.2
--- src/engine/test/test-transaction-reversal.c
+++ src/engine/test/test-transaction-reversal.c
@@ -49,12 +49,15 @@
if (!acc1 || !acc2)
{
failure("accounts not created");
+ return;
}
+ /* Find a transaction that isn't voided */
do
{
transaction = get_random_transaction (book);
- if (xaccTransGetVoidStatus (transaction))
+ gboolean voyd = xaccTransGetVoidStatus (transaction);
+ if (voyd)
{
xaccTransBeginEdit (transaction);
xaccTransDestroy (transaction);
@@ -62,13 +65,14 @@
transaction = NULL;
}
} while (!transaction);
-
transaction_set_splits_to_accounts(transaction, acc1, acc2);
xaccTransSortSplits(transaction);
new_trans = xaccTransClone(transaction);
if (!xaccTransEqual(transaction, new_trans, FALSE, TRUE, FALSE, TRUE))
+ {
failure("xaccTransClone failed.");
+ }
xaccTransReverse(new_trans);
for (i = 0; i < 2; i++)
@@ -78,7 +82,7 @@
result = gnc_numeric_add(old, new, GNC_DENOM_AUTO, GNC_DENOM_FIXED);
if (gnc_numeric_eq(old, gnc_numeric_neg(new)))
{
- msg = g_strdup_printf("Amount of split %d wrong after reversal", i);
+ msg = g_strdup_printf("Amount of split %d wrong after reversal\n", i);
failure(msg);
}
@@ -87,7 +91,7 @@
result = gnc_numeric_add(old, new, GNC_DENOM_AUTO, GNC_DENOM_FIXED);
if (gnc_numeric_eq(old, gnc_numeric_neg(new)))
{
- msg = g_strdup_printf("Value of split %d wrong after reversal", i);
+ msg = g_strdup_printf("Value of split %d wrong after reversal\n", i);
failure(msg);
}
@@ -101,6 +105,7 @@
gnc_module_load("gnucash/engine", 0);
xaccLogDisable ();
+ set_success_print (TRUE);
run_test ();
Index: test-engine-stuff.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/test-core/test-engine-stuff.c,v
retrieving revision 1.52.4.7
retrieving revision 1.52.4.8
diff -Lsrc/engine/test-core/test-engine-stuff.c -Lsrc/engine/test-core/test-engine-stuff.c -u -r1.52.4.7 -r1.52.4.8
--- src/engine/test-core/test-engine-stuff.c
+++ src/engine/test-core/test-engine-stuff.c
@@ -4,6 +4,14 @@
* Create transactions with random values, random accounts, random
* account heirarchies, etc.
*
+ * XXX We should modify routines to create really, ugly, dirty
+ * transactions
+ * -- 3 or more splits (TBD)
+ * -- splits without parent accounts (done)
+ * -- splits that have accounts but aren't in a transaction (TBD)
+ * -- splits that share a currency with the transaction, but whose
+ * value doesn't equal amount (done)
+ *
* Created by Linux Developers Group, 2001
* Updates Linas Vepstas July 2004
*/
@@ -19,8 +27,10 @@
#include <sys/stat.h>
#include <unistd.h>
+#include "Account.h"
#include "AccountP.h"
#include "Group.h"
+#include "GroupP.h"
#include "gnc-date.h"
#include "gnc-engine.h"
#include "gnc-engine-util.h"
@@ -42,13 +52,19 @@
static gint max_total_accounts = 1000;
static gint total_num_accounts = 0;
-static kvp_value* get_random_kvp_value_depth (int type, gint depth);
-static gpointer get_random_list_element (GList *list);
-static void add_random_splits(QofBook *book, Transaction *trn, GList *account_list);
+
+/* The inverse fraction of split/transaction data that should
+ * contain invalid/inconsistent fields/values. Thus,
+ * if borked==1000, then one in 1000 fields will have bad data.
+ * This is used to test the data integrity scrubbers, which are
+ * supposed to clean up any crud they find.
+ */
+static gint borked = 80;
gboolean gnc_engine_debug_random = FALSE;
-/***********************************************************************/
+/* ========================================================== */
+/* Set control parameters governing the run. */
void
set_max_group_depth (gint max_group_depth_in)
@@ -124,6 +140,71 @@
usec_resolution = usec_resolution_in;
}
+/* ========================================================== */
+
+static inline gboolean
+do_bork (void)
+{
+ if (1 == get_random_int_in_range (0, borked))
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* ========================================================== */
+/* GList stuff */
+
+static gpointer
+get_random_list_element (GList *list)
+{
+ g_return_val_if_fail (list, NULL);
+
+ return g_list_nth_data (list,
+ get_random_int_in_range (0,
+ g_list_length (list) - 1));
+}
+
+static kvp_value* get_random_kvp_value_depth (int type, gint depth);
+
+static GList*
+get_random_glist_depth (gint depth)
+{
+ GList *ret = NULL;
+ int count = get_random_int_in_range(1, 5);
+ int i;
+
+ if (depth >= kvp_max_depth)
+ return NULL;
+
+ for (i = 0; i < count; i++)
+ {
+ KvpValueType kvpt;
+ KvpValue *value;
+
+ kvpt = glist_strings_only ? KVP_TYPE_STRING : -2;
+
+ do
+ {
+ value = get_random_kvp_value_depth (kvpt, depth + 1);
+ }
+ while (!value);
+
+ ret = g_list_prepend(ret, value);
+ }
+
+ return ret;
+}
+
+GList*
+get_random_glist(void)
+{
+ return get_random_glist_depth (0);
+}
+
+/* ========================================================== */
+/* Time/Date, GUID, binary data stuff */
+
Timespec*
get_random_timespec(void)
{
@@ -151,6 +232,204 @@
return ret;
}
+GUID*
+get_random_guid(void)
+{
+ GUID *ret;
+
+ ret = g_new(GUID, 1);
+ guid_new(ret);
+
+ return ret;
+}
+
+bin_data*
+get_random_binary_data(void)
+{
+ int len;
+ bin_data *ret;
+
+ len = get_random_int_in_range(20,100);
+ ret = g_new(bin_data, 1);
+ ret->data = g_new(char, len);
+ ret->len = len;
+
+ for(len--; len >= 0; len--)
+ {
+ ret->data[len] = (char)get_random_int_in_range(0,255);
+ }
+
+ return ret;
+}
+
+/* ========================================================== */
+/* KVP stuff */
+
+static KvpFrame* get_random_kvp_frame_depth (gint depth);
+
+static KvpValue*
+get_random_kvp_value_depth (int type, gint depth)
+{
+ int datype = type;
+
+ if (datype == -1)
+ {
+ datype = get_random_int_in_range(KVP_TYPE_GINT64, KVP_TYPE_FRAME);
+ }
+
+ if (datype == -2)
+ {
+ datype = get_random_int_in_range(KVP_TYPE_GINT64, KVP_TYPE_FRAME - 1);
+ }
+
+ if (datype == KVP_TYPE_FRAME && depth >= kvp_max_depth)
+ return NULL;
+
+ if (datype == KVP_TYPE_GLIST && depth >= kvp_max_depth)
+ return NULL;
+
+ if (kvp_type_excluded (datype))
+ return NULL;
+
+ switch(datype)
+ {
+ case KVP_TYPE_GINT64:
+ return kvp_value_new_gint64(get_random_gint64());
+ break;
+
+ case KVP_TYPE_DOUBLE:
+ return NULL;
+ break;
+
+ case KVP_TYPE_NUMERIC:
+ return kvp_value_new_gnc_numeric(get_random_gnc_numeric());
+ break;
+
+ case KVP_TYPE_STRING:
+ {
+ gchar *tmp_str;
+ KvpValue *ret;
+ tmp_str = get_random_string();
+ if(!tmp_str)
+ {
+ return NULL;
+ }
+
+ ret = kvp_value_new_string(tmp_str);
+ g_free(tmp_str);
+ return ret;
+ }
+ break;
+
+ case KVP_TYPE_GUID:
+ {
+ GUID *tmp_guid;
+ KvpValue *ret;
+ tmp_guid = get_random_guid();
+ ret = kvp_value_new_guid(tmp_guid);
+ g_free(tmp_guid);
+ return ret;
+ }
+ break;
+
+ case KVP_TYPE_TIMESPEC:
+ {
+ Timespec *ts = get_random_timespec();
+ return kvp_value_new_timespec (*ts);
+ }
+ break;
+
+ case KVP_TYPE_BINARY:
+ {
+ bin_data *tmp_data;
+ KvpValue *ret;
+ tmp_data = get_random_binary_data();
+ ret = kvp_value_new_binary(tmp_data->data, tmp_data->len);
+ g_free(tmp_data->data);
+ g_free(tmp_data);
+ return ret;
+ }
+ break;
+
+ case KVP_TYPE_GLIST:
+ return kvp_value_new_glist_nc(get_random_glist_depth (depth + 1));
+ break;
+
+ case KVP_TYPE_FRAME:
+ {
+ KvpFrame *tmp_frame;
+ KvpValue *ret;
+ tmp_frame = get_random_kvp_frame_depth(depth + 1);
+ ret = kvp_value_new_frame(tmp_frame);
+ kvp_frame_delete(tmp_frame);
+ return ret;
+ }
+ break;
+
+ default:
+ return NULL;
+ break;
+ }
+}
+
+static KvpFrame*
+get_random_kvp_frame_depth (gint depth)
+{
+ KvpFrame *ret;
+ int vals_to_add;
+ gboolean val_added;
+
+ if (depth >= kvp_max_depth)
+ return NULL;
+
+ ret = kvp_frame_new();
+
+ vals_to_add = get_random_int_in_range(1,kvp_frame_max_elements);
+ val_added = FALSE;
+
+ for (;vals_to_add > 0; vals_to_add--)
+ {
+ gchar *key;
+ KvpValue *val;
+
+ do
+ {
+ key = get_random_string_without("/");
+ } while (!key || *key == '\0');
+
+ val = get_random_kvp_value_depth (-1, depth + 1);
+ if (!val)
+ {
+ if (!val_added)
+ vals_to_add++;
+ continue;
+ }
+
+ val_added = TRUE;
+
+ kvp_frame_set_slot_nc(ret, key, val);
+
+ g_free(key);
+ }
+
+ return ret;
+}
+
+KvpFrame *
+get_random_kvp_frame (void)
+{
+ return get_random_kvp_frame_depth (0);
+}
+
+KvpValue *
+get_random_kvp_value(int type)
+{
+ return get_random_kvp_value_depth (type, 0);
+}
+
+/* ================================================================= */
+/* Numeric stuff */
+
#define RAND_IN_RANGE(X) (((X)*((gint64) (rand()+1)))/RAND_MAX)
gnc_numeric
@@ -185,6 +464,9 @@
return gnc_numeric_create(numer, deno);
}
+/* ================================================================= */
+/* Commodity stuff */
+
const char *types[] =
{
"NASDAQ",
@@ -201,18 +483,168 @@
return get_random_string_in_array(types);
}
-void
-make_random_changes_to_price (QofBook *book, GNCPrice *p)
+static gnc_commodity *
+get_random_commodity_from_table (gnc_commodity_table *table)
{
- Timespec *ts;
- char *string;
- gnc_commodity *c;
+ GList *namespaces;
+ gnc_commodity *com = NULL;
- g_return_if_fail (book && p);
+ g_return_val_if_fail (table, NULL);
- gnc_price_begin_edit (p);
+ namespaces = gnc_commodity_table_get_namespaces (table);
- c = get_random_commodity (book);
+ do
+ {
+ GList *commodities;
+ char *namespace;
+
+ namespace = get_random_list_element (namespaces);
+
+ commodities = gnc_commodity_table_get_commodities (table, namespace);
+ if (!commodities)
+ continue;
+
+ com = get_random_list_element (commodities);
+
+ g_list_free (commodities);
+
+ } while (!com);
+
+
+ g_list_free (namespaces);
+
+ return com;
+}
+
+gnc_commodity*
+get_random_commodity (QofBook *book)
+{
+ gnc_commodity *ret;
+ gchar *name;
+ const gchar *space;
+ gchar *mn;
+ gchar *xcode;
+ int ran_int;
+ gnc_commodity_table *table;
+
+ table = gnc_commodity_table_get_table (book);
+
+#if 0
+ if (table &&
+ (gnc_commodity_table_get_size (table) > 0) &&
+ get_random_int_in_range (1, 5) < 5)
+ return get_random_commodity_from_table (table);
+#endif
+
+ mn = get_random_string();
+ space = get_random_commodity_namespace();
+
+ if (table)
+ {
+ ret = gnc_commodity_table_lookup (table, space, mn);
+
+ if (ret)
+ {
+ g_free (mn);
+ return ret;
+ }
+ }
+
+ name = get_random_string();
+ xcode = get_random_string();
+
+ /* SCU == smallest currency unit -- the value of the denominator */
+#define MAX_SCU 6000
+ ran_int = get_random_int_in_range(1, MAX_SCU);
+
+ ret = gnc_commodity_new (book, name, space, mn, xcode, ran_int);
+
+ g_free(mn);
+ g_free(name);
+ g_free(xcode);
+
+ if (table)
+ ret = gnc_commodity_table_insert (table, ret);
+
+ return ret;
+}
+
+void
+make_random_changes_to_commodity (gnc_commodity *com)
+{
+ char *str;
+
+ g_return_if_fail (com);
+
+ str = get_random_string ();
+ gnc_commodity_set_namespace (com, str);
+ g_free (str);
+
+ str = get_random_string ();
+ gnc_commodity_set_mnemonic (com, str);
+ g_free (str);
+
+ str = get_random_string ();
+ gnc_commodity_set_fullname (com, str);
+ g_free (str);
+
+ str = get_random_string ();
+ gnc_commodity_set_exchange_code (com, str);
+ g_free (str);
+
+ gnc_commodity_set_fraction (com, get_random_int_in_range (1, 100000));
+}
+
+void
+make_random_changes_to_commodity_table (gnc_commodity_table *table)
+{
+ GList *namespaces;
+ GList *node;
+
+ g_return_if_fail (table);
+
+ namespaces = gnc_commodity_table_get_namespaces (table);
+
+ for (node = namespaces; node; node = node->next)
+ {
+ const char *ns = node->data;
+ GList *commodities;
+ GList *com_node;
+
+ if (gnc_commodity_namespace_is_iso (ns))
+ continue;
+
+ commodities = gnc_commodity_table_get_commodities (table, ns);
+
+ for (com_node = commodities; com_node; com_node = com_node->next)
+ {
+ gnc_commodity *com = com_node->data;
+
+ gnc_commodity_table_remove (table, com);
+ make_random_changes_to_commodity (com);
+ gnc_commodity_table_insert (table, com);
+ }
+
+ g_list_free (commodities);
+ }
+
+ g_list_free (namespaces);
+}
+/* ================================================================= */
+/* Price stuff */
+
+void
+make_random_changes_to_price (QofBook *book, GNCPrice *p)
+{
+ Timespec *ts;
+ char *string;
+ gnc_commodity *c;
+
+ g_return_if_fail (book && p);
+
+ gnc_price_begin_edit (p);
+
+ c = get_random_commodity (book);
gnc_price_set_commodity (p, c);
c = get_random_commodity (book);
@@ -271,7 +703,8 @@
{
GNCPriceDB *db;
- db = gnc_pricedb_create (book);
+ // db = gnc_pricedb_create (book);
+ db = gnc_pricedb_get_db (book);
make_random_pricedb (book, db);
return db;
@@ -301,264 +734,42 @@
{
GNCPrice *p = node->data;
- switch (get_random_int_in_range (0, 5))
- {
- case 0: /* Delete */
- gnc_pricedb_remove_price (pdb, p);
- break;
-
- case 1:
- case 2: /* Change */
- make_random_changes_to_price (book, p);
- break;
-
- default: /* nothing */
- break;
- }
- }
-
- g_list_free (list);
-
- /* Add a few new ones */
- {
- int i = get_random_int_in_range (1, 5);
-
- while (i--)
- {
- GNCPrice *p = get_random_price (book);
-
- gnc_pricedb_add_price (pdb, p);
-
- gnc_price_unref (p);
- }
- }
-}
-
-GUID*
-get_random_guid(void)
-{
- GUID *ret;
-
- ret = g_new(GUID, 1);
- guid_new(ret);
-
- return ret;
-}
-
-static GList*
-get_random_glist_depth (gint depth)
-{
- GList *ret = NULL;
- int count = get_random_int_in_range(1, 5);
- int i;
-
- if (depth >= kvp_max_depth)
- return NULL;
-
- for (i = 0; i < count; i++)
- {
- KvpValueType kvpt;
- kvp_value *value;
-
- kvpt = glist_strings_only ? KVP_TYPE_STRING : -2;
-
- do
- {
- value = get_random_kvp_value_depth (kvpt, depth + 1);
- }
- while (!value);
-
- ret = g_list_prepend(ret, value);
- }
-
- return ret;
-}
-
-GList*
-get_random_glist(void)
-{
- return get_random_glist_depth (0);
-}
-
-bin_data*
-get_random_binary_data(void)
-{
- int len;
- bin_data *ret;
-
- len = get_random_int_in_range(20,100);
- ret = g_new(bin_data, 1);
- ret->data = g_new(char, len);
- ret->len = len;
-
- for(len--; len >= 0; len--)
- {
- ret->data[len] = (char)get_random_int_in_range(0,255);
- }
-
- return ret;
-}
-
-static kvp_frame*
-get_random_kvp_frame_depth (gint depth)
-{
- kvp_frame *ret;
- int vals_to_add;
- gboolean val_added;
-
- if (depth >= kvp_max_depth)
- return NULL;
-
- ret = kvp_frame_new();
-
- vals_to_add = get_random_int_in_range(1,kvp_frame_max_elements);
- val_added = FALSE;
-
- for (;vals_to_add > 0; vals_to_add--)
- {
- gchar *key;
- kvp_value *val;
-
- do
- {
- key = get_random_string_without("/");
- } while (!key || *key == '\0');
-
- val = get_random_kvp_value_depth (-1, depth + 1);
- if (!val)
- {
- if (!val_added)
- vals_to_add++;
- continue;
- }
-
- val_added = TRUE;
-
- kvp_frame_set_slot_nc(ret, key, val);
-
- g_free(key);
- }
-
- return ret;
-}
-
-kvp_frame*
-get_random_kvp_frame (void)
-{
- return get_random_kvp_frame_depth (0);
-}
-
-static kvp_value*
-get_random_kvp_value_depth (int type, gint depth)
-{
- int datype = type;
-
- if (datype == -1)
- {
- datype = get_random_int_in_range(KVP_TYPE_GINT64, KVP_TYPE_FRAME);
- }
-
- if (datype == -2)
- {
- datype = get_random_int_in_range(KVP_TYPE_GINT64, KVP_TYPE_FRAME - 1);
- }
-
- if (datype == KVP_TYPE_FRAME && depth >= kvp_max_depth)
- return NULL;
-
- if (datype == KVP_TYPE_GLIST && depth >= kvp_max_depth)
- return NULL;
-
- if (kvp_type_excluded (datype))
- return NULL;
-
- switch(datype)
- {
- case KVP_TYPE_GINT64:
- return kvp_value_new_gint64(get_random_gint64());
- break;
-
- case KVP_TYPE_DOUBLE:
- return NULL;
- break;
-
- case KVP_TYPE_NUMERIC:
- return kvp_value_new_gnc_numeric(get_random_gnc_numeric());
- break;
-
- case KVP_TYPE_STRING:
- {
- gchar *tmp_str;
- kvp_value *ret;
- tmp_str = get_random_string();
- if(!tmp_str)
- {
- return NULL;
- }
-
- ret = kvp_value_new_string(tmp_str);
- g_free(tmp_str);
- return ret;
- }
- break;
-
- case KVP_TYPE_GUID:
- {
- GUID *tmp_guid;
- kvp_value *ret;
- tmp_guid = get_random_guid();
- ret = kvp_value_new_guid(tmp_guid);
- g_free(tmp_guid);
- return ret;
- }
- break;
-
- case KVP_TYPE_TIMESPEC:
- {
- Timespec *ts = get_random_timespec();
- return kvp_value_new_timespec (*ts);
- }
- break;
-
- case KVP_TYPE_BINARY:
+ switch (get_random_int_in_range (0, 5))
{
- bin_data *tmp_data;
- kvp_value *ret;
- tmp_data = get_random_binary_data();
- ret = kvp_value_new_binary(tmp_data->data, tmp_data->len);
- g_free(tmp_data->data);
- g_free(tmp_data);
- return ret;
- }
- break;
-
- case KVP_TYPE_GLIST:
- return kvp_value_new_glist_nc(get_random_glist_depth (depth + 1));
+ case 0: /* Delete */
+ gnc_pricedb_remove_price (pdb, p);
break;
- case KVP_TYPE_FRAME:
- {
- kvp_frame *tmp_frame;
- kvp_value *ret;
- tmp_frame = get_random_kvp_frame_depth(depth + 1);
- ret = kvp_value_new_frame(tmp_frame);
- kvp_frame_delete(tmp_frame);
- return ret;
- }
+ case 1:
+ case 2: /* Change */
+ make_random_changes_to_price (book, p);
break;
- default:
- return NULL;
+ default: /* nothing */
break;
}
-}
+ }
-kvp_value *
-get_random_kvp_value(int type)
-{
- return get_random_kvp_value_depth (type, 0);
+ g_list_free (list);
+
+ /* Add a few new ones */
+ {
+ int i = get_random_int_in_range (1, 5);
+
+ while (i--)
+ {
+ GNCPrice *p = get_random_price (book);
+
+ gnc_pricedb_add_price (pdb, p);
+
+ gnc_price_unref (p);
+ }
+ }
}
+/* ================================================================= */
+/* Account stuff */
+
static void
set_account_random_string(Account* act,
void(*func)(Account *act, const gchar*str))
@@ -617,7 +828,7 @@
}
static void
-make_random_group (QofBook *book, AccountGroup * group)
+make_random_group (QofBook *book, AccountGroup *group)
{
int depth;
@@ -637,13 +848,91 @@
g_return_val_if_fail (book, NULL);
- group = xaccMallocAccountGroup (book);
+ group = xaccGetAccountGroup (book);
+ if (!group)
+ {
+ group = xaccMallocAccountGroup (book);
+ xaccSetAccountGroup (book, group);
+ }
make_random_group (book, group);
return group;
}
+/* ================================================================= */
+/* transaction stuff */
+
+/** This routine creates a random, but otherwise self-consistent,
+ * 'legal' transaction. It's been modified to occasionally build
+ * cruddy, inconsistent transactions, so that the engine 'scrub'
+ * routines get tested.
+ */
+static void
+add_random_splits(QofBook *book, Transaction *trn, GList *account_list)
+{
+ Account *acc, *bcc;
+ Split *s;
+
+ /* Gotta have at least two different accounts */
+ if (1 >= g_list_length (account_list)) return;
+
+ /* Set up two splits whose values really are opposites. */
+ gnc_commodity *com = xaccTransGetCurrency (trn);
+ int scu = gnc_commodity_get_fraction(com);
+ gnc_numeric num = get_random_gnc_numeric();
+
+ if (!do_bork()) num = gnc_numeric_convert (num, scu, GNC_HOW_RND_ROUND);
+
+ acc = get_random_list_element (account_list);
+ s = get_random_split(book, acc);
+ xaccTransAppendSplit(trn, s);
+ xaccSplitSetValue(s, num);
+
+ /* If the currencies are the same, the split amount should equal
+ * the split value (unless we bork it on purpose) */
+ if (gnc_commodity_equal (xaccTransGetCurrency(trn),
+ xaccAccountGetCommodity(acc)) &&
+ (!do_bork()))
+ {
+ xaccSplitSetAmount(s, num);
+ }
+
+ /* Occasionally leave a dangling split around */
+ if (do_bork()) xaccAccountRemoveSplit (s->acc, s);
+
+ bcc = get_random_list_element (account_list);
+ if ((bcc == acc) && (!do_bork()))
+ {
+ /* Make sure that each side of the transaction is in
+ * a different account; otherwise get weirdness in lot
+ * calculcations. ... Hmm maybe should fix lots in
+ * this case? */
+ while (bcc == acc) {
+ bcc = get_random_list_element (account_list);
+ }
+ }
+
+ s = get_random_split(book, bcc);
+ xaccTransAppendSplit(trn, s);
+
+ /* Other split should have equal and opposite value */
+ if (do_bork())
+ {
+ num = get_random_gnc_numeric();
+ }
+ xaccSplitSetValue(s, gnc_numeric_neg(num));
+
+ if (gnc_commodity_equal (xaccTransGetCurrency(trn),
+ xaccAccountGetCommodity(bcc)) &&
+ (!do_bork()))
+ {
+ xaccSplitSetAmount(s, num);
+ }
+
+ if (do_bork()) xaccAccountRemoveSplit (s->acc, s);
+}
+
typedef struct
{
GUID guid;
@@ -875,6 +1164,7 @@
Account*
get_random_account(QofBook *book)
{
+ AccountGroup *grp;
Account *ret;
int tmp_int;
@@ -894,6 +1184,13 @@
xaccAccountSetSlots_nc(ret, get_random_kvp_frame());
+ grp = xaccGetAccountGroup (book);
+ if (!grp)
+ {
+ grp = xaccMallocAccountGroup (book);
+ xaccSetAccountGroup (book, grp);
+ }
+ xaccGroupInsertAccount (grp, ret);
xaccAccountCommitEdit(ret);
return ret;
@@ -1003,29 +1300,6 @@
}
static void
-add_random_splits(QofBook *book, Transaction *trn, GList *account_list)
-{
- Account *account;
- Split *s;
-
- /* Set up two splits whose values really are opposites. */
- gnc_commodity *com = xaccTransGetCurrency (trn);
- int scu = gnc_commodity_get_fraction(com);
- gnc_numeric num = get_random_gnc_numeric();
- num = gnc_numeric_convert (num, scu, GNC_HOW_RND_ROUND);
-
- account = get_random_list_element (account_list);
- s = get_random_split(book, account);
- xaccTransAppendSplit(trn, s);
- xaccSplitSetValue(s, num);
-
- account = get_random_list_element (account_list);
- s = get_random_split(book, account);
- xaccTransAppendSplit(trn, s);
- xaccSplitSetValue(s, gnc_numeric_neg(num));
-}
-
-static void
trn_add_ran_timespec(Transaction *trn, void (*func)(Transaction*,
const Timespec*))
{
@@ -1046,9 +1320,12 @@
if (!account_list)
{
- account_list = xaccGroupGetSubAccounts (gnc_book_get_group (book));
+ account_list = xaccGroupGetSubAccounts (xaccGetAccountGroup (book));
}
+ /* Gotta have at least two different accounts */
+ if (1 >= g_list_length (account_list)) return NULL;
+
ret = xaccMallocTransaction(book);
xaccTransBeginEdit(ret);
@@ -1061,7 +1338,8 @@
trn_add_ran_timespec(ret, xaccTransSetDatePostedTS);
trn_add_ran_timespec(ret, xaccTransSetDateEnteredTS);
- xaccTransSetSlots_nc(ret, get_random_kvp_frame());
+ KvpFrame *f = get_random_kvp_frame();
+ xaccTransSetSlots_nc(ret, f);
add_random_splits(book, ret, account_list);
@@ -1111,163 +1389,6 @@
xaccTransCommitEdit (trans);
}
-static gpointer
-get_random_list_element (GList *list)
-{
- g_return_val_if_fail (list, NULL);
-
- return g_list_nth_data (list,
- get_random_int_in_range (0,
- g_list_length (list) - 1));
-}
-
-static gnc_commodity *
-get_random_commodity_from_table (gnc_commodity_table *table)
-{
- GList *namespaces;
- gnc_commodity *com = NULL;
-
- g_return_val_if_fail (table, NULL);
-
- namespaces = gnc_commodity_table_get_namespaces (table);
-
- do
- {
- GList *commodities;
- char *namespace;
-
- namespace = get_random_list_element (namespaces);
-
- commodities = gnc_commodity_table_get_commodities (table, namespace);
- if (!commodities)
- continue;
-
- com = get_random_list_element (commodities);
-
- g_list_free (commodities);
-
- } while (!com);
-
-
- g_list_free (namespaces);
-
- return com;
-}
-
-gnc_commodity*
-get_random_commodity (QofBook *book)
-{
- gnc_commodity *ret;
- gchar *name;
- const gchar *space;
- gchar *mn;
- gchar *xcode;
- int ran_int;
- gnc_commodity_table *table;
-
- table = gnc_book_get_commodity_table (book);
-
-#if 0
- if (table &&
- (gnc_commodity_table_get_size (table) > 0) &&
- get_random_int_in_range (1, 5) < 5)
- return get_random_commodity_from_table (table);
-#endif
-
- mn = get_random_string();
- space = get_random_commodity_namespace();
-
- if (table)
- {
- ret = gnc_commodity_table_lookup (table, space, mn);
-
- if (ret)
- {
- g_free (mn);
- return ret;
- }
- }
-
- name = get_random_string();
- xcode = get_random_string();
-
- /* SCU == smallest currency unit -- the value of the denominator */
-#define MAX_SCU 6000
- ran_int = get_random_int_in_range(1, MAX_SCU);
-
- ret = gnc_commodity_new (book, name, space, mn, xcode, ran_int);
-
- g_free(mn);
- g_free(name);
- g_free(xcode);
-
- if (table)
- ret = gnc_commodity_table_insert (table, ret);
-
- return ret;
-}
-
-void
-make_random_changes_to_commodity (gnc_commodity *com)
-{
- char *str;
-
- g_return_if_fail (com);
-
- str = get_random_string ();
- gnc_commodity_set_namespace (com, str);
- g_free (str);
-
- str = get_random_string ();
- gnc_commodity_set_mnemonic (com, str);
- g_free (str);
-
- str = get_random_string ();
- gnc_commodity_set_fullname (com, str);
- g_free (str);
-
- str = get_random_string ();
- gnc_commodity_set_exchange_code (com, str);
- g_free (str);
-
- gnc_commodity_set_fraction (com, get_random_int_in_range (1, 100000));
-}
-
-void
-make_random_changes_to_commodity_table (gnc_commodity_table *table)
-{
- GList *namespaces;
- GList *node;
-
- g_return_if_fail (table);
-
- namespaces = gnc_commodity_table_get_namespaces (table);
-
- for (node = namespaces; node; node = node->next)
- {
- const char *ns = node->data;
- GList *commodities;
- GList *com_node;
-
- if (gnc_commodity_namespace_is_iso (ns))
- continue;
-
- commodities = gnc_commodity_table_get_commodities (table, ns);
-
- for (com_node = commodities; com_node; com_node = com_node->next)
- {
- gnc_commodity *com = com_node->data;
-
- gnc_commodity_table_remove (table, com);
- make_random_changes_to_commodity (com);
- gnc_commodity_table_insert (table, com);
- }
-
- g_list_free (commodities);
- }
-
- g_list_free (namespaces);
-}
static GList *
get_random_guids(int max)
@@ -1427,7 +1548,7 @@
while (num_terms-- > 0)
{
gint pr_type;
- kvp_value *value;
+ KvpValue *value;
Timespec *start;
Timespec *end;
GList *guids;
@@ -1599,8 +1720,8 @@
book = qof_book_new ();
- make_random_group (book, gnc_book_get_group (book));
- make_random_pricedb (book, gnc_book_get_pricedb (book));
+ get_random_group (book);
+ get_random_pricedb (book);
return book;
}
@@ -1615,8 +1736,8 @@
book = qof_session_get_book (session);
- make_random_group (book, gnc_book_get_group (book));
- make_random_pricedb (book, gnc_book_get_pricedb (book));
+ get_random_group (book);
+ get_random_pricedb (book);
return session;
}
@@ -1632,13 +1753,13 @@
g_return_if_fail (book);
- accounts = xaccGroupGetSubAccounts (gnc_book_get_group (book));
+ accounts = xaccGroupGetSubAccounts (xaccGetAccountGroup (book));
g_return_if_fail (accounts);
num_accounts = g_list_length (accounts);
- table = gnc_book_get_commodity_table (book);
+ table = gnc_commodity_table_get_table (book);
while (num_transactions--)
{
@@ -1656,11 +1777,11 @@
{
g_return_if_fail (book);
- make_random_changes_to_group (book, gnc_book_get_group (book));
- make_random_changes_to_pricedb (book, gnc_book_get_pricedb (book));
+ make_random_changes_to_group (book, xaccGetAccountGroup (book));
+ make_random_changes_to_pricedb (book, gnc_pricedb_get_db (book));
#if 0
- make_random_changes_to_commodity_table (gnc_book_get_commodity_table (book));
+ make_random_changes_to_commodity_table (gnc_commodity_table_get_table (book));
#endif
}
@@ -1680,7 +1801,7 @@
} KVPQueryData;
static void
-add_kvp_value_query (const char *key, kvp_value *value, gpointer data)
+add_kvp_value_query (const char *key, KvpValue *value, gpointer data)
{
KVPQueryData *kqd = data;
GSList *node;
@@ -1701,7 +1822,7 @@
}
static void
-add_kvp_query (Query *q, kvp_frame *frame, QofIdType where)
+add_kvp_query (Query *q, KvpFrame *frame, QofIdType where)
{
KVPQueryData kqd;
Index: gnucash.desktop.in
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/gnome/gnucash.desktop.in,v
retrieving revision 1.2.4.1
retrieving revision 1.2.4.2
diff -Lsrc/gnome/gnucash.desktop.in -Lsrc/gnome/gnucash.desktop.in -u -r1.2.4.1 -r1.2.4.2
--- src/gnome/gnucash.desktop.in
+++ src/gnome/gnucash.desktop.in
@@ -1,6 +1,7 @@
[Desktop Entry]
_Name=GnuCash
-_Comment=GnuCash Personal Finance
+_GenericName=Money Management
+_Comment=Manage your finances, accounts, and investments
TryExec=gnucash
Exec=gnucash
Icon=gnucash/gnucash-icon.png
Index: qif-dialog-utils.scm
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/import-export/qif-import/qif-dialog-utils.scm,v
retrieving revision 1.3.4.2
retrieving revision 1.3.4.3
diff -Lsrc/import-export/qif-import/qif-dialog-utils.scm -Lsrc/import-export/qif-import/qif-dialog-utils.scm -u -r1.3.4.2 -r1.3.4.3
--- src/import-export/qif-import/qif-dialog-utils.scm
+++ src/import-export/qif-import/qif-dialog-utils.scm
@@ -18,8 +18,11 @@
(define (default-interest-acct brokerage security)
(string-append (_ "Interest") (gnc:account-separator-char)
- brokerage (gnc:account-separator-char)
- security))
+ brokerage
+ (if (string=? security "")
+ ""
+ (string-append (gnc:account-separator-char)
+ security))))
(define (default-capital-return-acct brokerage security)
(string-append (_ "Cap Return") (gnc:account-separator-char)
Index: report-system.scm
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/report/report-system/report-system.scm,v
retrieving revision 1.20.4.2
retrieving revision 1.20.4.3
diff -Lsrc/report/report-system/report-system.scm -Lsrc/report/report-system/report-system.scm -u -r1.20.4.2 -r1.20.4.3
--- src/report/report-system/report-system.scm
+++ src/report/report-system/report-system.scm
@@ -68,6 +68,7 @@
;; html-utilities.scm
+(export gnc:html-make-empty-cell)
(export gnc:html-make-empty-cells)
(export gnc:account-anchor-text)
(export gnc:split-anchor-text)
@@ -593,6 +594,9 @@
(export gnc:report-finished)
(export gnc:accounts-count-splits)
(export gnc:commodity-collector-allzero?)
+(export gnc:account-get-trans-type-balance-interval)
+(export gnc:account-get-pos-trans-total-interval)
+(export gnc:double-col)
(load-from-path "commodity-utilities.scm")
(load-from-path "html-barchart.scm")
Index: html-table.scm
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/report/report-system/html-table.scm,v
retrieving revision 1.1.6.1
retrieving revision 1.1.6.2
diff -Lsrc/report/report-system/html-table.scm -Lsrc/report/report-system/html-table.scm -u -r1.1.6.1 -r1.1.6.2
--- src/report/report-system/html-table.scm
+++ src/report/report-system/html-table.scm
@@ -405,19 +405,25 @@
;; (let ((a '(0 1 2))) (list-set! a 1 "x") a)
;; => (0 "x" 2)
(define (gnc:html-table-get-cell table row col)
- (list-ref-safe (gnc:html-table-get-row table row) col))
+ (let* ((row (gnc:html-table-get-row table row)))
+ (and row (list-ref-safe row col)))
+ )
(define (gnc:html-table-get-row table row)
(let* ((dd (gnc:html-table-data table))
- (len (length dd))
+ (len (and dd (length dd)))
+ )
+ (and len
+ (list-ref-safe dd (- (- len 1) row))
)
- (list-ref-safe dd (- (- len 1) row))
))
(define (gnc:html-table-set-cell! table row col . objects)
(let ((rowdata #f)
(row-loc #f)
- (l (length (gnc:html-table-data table))))
+ (l (length (gnc:html-table-data table)))
+ (objs (length objects))
+ )
;; ensure the row-data is there
(if (>= row l)
(begin
@@ -433,8 +439,12 @@
(set! rowdata (list-ref (gnc:html-table-data table) row-loc))))
;; make a table-cell and set the data
- (let ((tc (gnc:make-html-table-cell)))
- (apply gnc:html-table-cell-append-objects! tc objects)
+ (let* ((tc (gnc:make-html-table-cell))
+ (first (car objects)))
+ (if (and (equal? objs 1) (gnc:html-table-cell? first))
+ (set! tc first)
+ (apply gnc:html-table-cell-append-objects! tc objects)
+ )
(set! rowdata (list-set-safe! rowdata col tc))
;; add the row-data back to the table
Index: commodity-utilities.scm
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/report/report-system/commodity-utilities.scm,v
retrieving revision 1.11.4.2
retrieving revision 1.11.4.3
diff -Lsrc/report/report-system/commodity-utilities.scm -Lsrc/report/report-system/commodity-utilities.scm -u -r1.11.4.2 -r1.11.4.3
--- src/report/report-system/commodity-utilities.scm
+++ src/report/report-system/commodity-utilities.scm
@@ -906,3 +906,30 @@
#f)
balance)
#f))
+
+;; Returns the number of commodities in a commodity-collector.
+;; (If this were implemented as a record, I would be able to
+;; just (length ...) the alist, but....)
+(define (gnc:commodity-collector-commodity-count collector)
+ (let ((commodities 0))
+ (gnc:commodity-collector-map
+ collector
+ (lambda (comm amt)
+ (set! commodities (+ commodities 1))))
+ commodities
+ ))
+
+(define (gnc:uniform-commodity? amt report-commodity)
+ ;; function to see if the commodity-collector amt
+ ;; contains any foreign commodities
+ (let ((elts (gnc:commodity-collector-commodity-count amt))
+ )
+ (or (equal? elts 0)
+ (and (equal? elts 1)
+ (gnc:commodity-collector-contains-commodity?
+ amt report-commodity)
+ )
+ )
+ )
+ )
+
Index: report-utilities.scm
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/report/report-system/report-utilities.scm,v
retrieving revision 1.18.4.2
retrieving revision 1.18.4.3
diff -Lsrc/report/report-system/report-utilities.scm -Lsrc/report/report-system/report-utilities.scm -u -r1.18.4.2 -r1.18.4.3
--- src/report/report-system/report-utilities.scm
+++ src/report/report-system/report-utilities.scm
@@ -474,17 +474,6 @@
(define (gnc:commodity-collector-list collector)
(collector 'list #f #f))
-;; Returns the number of commodities in a commodity-collector.
-;; (If this were implemented as a record, I would be able to
-;; just (length ...) the alist, but....)
-(define (gnc:commodity-collector-commodity-count collector)
- (let ((commodities 0))
- (gnc:commodity-collector-map
- collector
- (lambda (comm amt) (set! commodities (+ commodities 1))))
- commodities
- ))
-
;; Returns zero if all entries in this collector are zero.
(define (gnc:commodity-collector-allzero? collector)
(let ((result #t))
@@ -706,3 +695,149 @@
(gnc:accounts-count-splits (cdr accounts)))
0))
+;; Sums up any splits of a certain type affecting a group of accounts.
+;; the type is an alist '((str "match me") (cased #f) (regexp #f))
+(define (gnc:account-get-trans-type-balance-interval
+ group type start-date-tp end-date-tp)
+ (let* ((query (gnc:malloc-query))
+ (splits #f)
+ (get-val (lambda (alist key)
+ (let ((lst (assoc-ref alist key)))
+ (if lst (car lst) lst))))
+ (matchstr (get-val type 'str))
+ (case-sens (if (get-val type 'cased) 1 0))
+ (regexp (if (get-val type 'regexp) 1 0))
+ (total (gnc:make-commodity-collector))
+ )
+ (gnc:query-set-book query (gnc:get-current-book))
+ (gnc:query-set-match-non-voids-only! query (gnc:get-current-book))
+ (gnc:query-add-account-match query group 'guid-match-any 'query-and)
+ (gnc:query-add-date-match-timepair
+ query
+ (and start-date-tp #t) start-date-tp
+ (and end-date-tp #t) end-date-tp 'query-and)
+ (gnc:query-add-description-match
+ query matchstr case-sens regexp 'query-and)
+
+ (set! splits (gnc:query-get-splits query))
+ (map (lambda (split)
+ (let* ((shares (gnc:split-get-amount split))
+ (acct-comm (gnc:account-get-commodity
+ (gnc:split-get-account split)))
+ )
+ (gnc:commodity-collector-add total acct-comm shares)
+ )
+ )
+ splits
+ )
+ (gnc:free-query query)
+ total
+ )
+ )
+
+;; similar, but only counts transactions with non-negative shares and
+;; *ignores* any closing entries
+(define (gnc:account-get-pos-trans-total-interval
+ group type start-date-tp end-date-tp)
+ (let* ((str-query (gnc:malloc-query))
+ (sign-query (gnc:malloc-query))
+ (total-query #f)
+ (splits #f)
+ (get-val (lambda (alist key)
+ (let ((lst (assoc-ref alist key)))
+ (if lst (car lst) lst))))
+ (matchstr (get-val type 'str))
+ (case-sens (if (get-val type 'cased) 1 0))
+ (regexp (if (get-val type 'regexp) 1 0))
+ (pos? (if (get-val type 'positive) #t #f))
+ (total (gnc:make-commodity-collector))
+ )
+ (gnc:query-set-book str-query (gnc:get-current-book))
+ (gnc:query-set-book sign-query (gnc:get-current-book))
+ (gnc:query-set-match-non-voids-only! str-query (gnc:get-current-book))
+ (gnc:query-set-match-non-voids-only! sign-query (gnc:get-current-book))
+ (gnc:query-add-account-match str-query group 'guid-match-any 'query-and)
+ (gnc:query-add-account-match sign-query group 'guid-match-any 'query-and)
+ (gnc:query-add-date-match-timepair
+ str-query
+ (and start-date-tp #t) start-date-tp
+ (and end-date-tp #t) end-date-tp 'query-and)
+ (gnc:query-add-date-match-timepair
+ sign-query
+ (and start-date-tp #t) start-date-tp
+ (and end-date-tp #t) end-date-tp 'query-and)
+ (gnc:query-add-description-match
+ str-query matchstr case-sens regexp 'query-and)
+ (set! total-query
+ ;; this is a tad inefficient, but its a simple way to accomplish
+ ;; description match inversion...
+ (if pos?
+ (gnc:query-merge sign-query str-query 'query-and)
+ (gnc:query-merge
+ sign-query (gnc:query-invert str-query) 'query-and)
+ ))
+
+ (set! splits (gnc:query-get-splits total-query))
+ (map (lambda (split)
+ (let* ((shares (gnc:split-get-amount split))
+ (acct-comm (gnc:account-get-commodity
+ (gnc:split-get-account split)))
+ )
+ (or (gnc:numeric-negative-p shares)
+ (gnc:commodity-collector-add total acct-comm shares)
+ )
+ )
+ )
+ splits
+ )
+ (gnc:free-query total-query)
+ total
+ )
+ )
+
+;; utility to assist with double-column balance tables
+;; a request is made with the <req> argument
+;; <req> may currently be 'entry|'debit-q|'credit-q|'zero-q|'debit|'credit
+;; 'debit-q|'credit-q|'zero-q tests the sign of the balance
+;; 'side returns 'debit or 'credit, the column in which to display
+;; 'debt|'credit return the entry, if appropriate, or #f
+(define (gnc:double-col
+ req signed-balance report-commodity exchange-fn show-comm?)
+ (let* ((sum (and signed-balance
+ (gnc:sum-collector-commodity
+ signed-balance
+ report-commodity
+ exchange-fn)))
+ (amt (and sum (gnc:gnc-monetary-amount sum)))
+ (neg? (and amt (gnc:numeric-negative-p amt)))
+ (bal (if neg?
+ (let ((bal (gnc:make-commodity-collector)))
+ (bal 'minusmerge signed-balance #f)
+ bal)
+ signed-balance))
+ (bal-sum (gnc:sum-collector-commodity
+ bal
+ report-commodity
+ exchange-fn))
+ (balance
+ (if (gnc:uniform-commodity? bal report-commodity)
+ (if (gnc:numeric-zero-p amt) #f bal-sum)
+ (if show-comm?
+ (gnc:commodity-table bal report-commodity exchange-fn)
+ bal-sum)
+ ))
+ )
+ (car (assoc-ref
+ (list
+ (list 'entry balance)
+ (list 'debit (if neg? #f balance))
+ (list 'credit (if neg? balance #f))
+ (list 'zero-q (if neg? #f (if balance #f #t)))
+ (list 'debit-q (if neg? #f (if balance #t #f)))
+ (list 'credit-q (if neg? #t #f))
+ )
+ req
+ ))
+ )
+ )
+
Index: html-acct-table.scm
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/report/report-system/html-acct-table.scm,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -Lsrc/report/report-system/html-acct-table.scm -Lsrc/report/report-system/html-acct-table.scm -u -r1.1.2.1 -r1.1.2.2
--- src/report/report-system/html-acct-table.scm
+++ src/report/report-system/html-acct-table.scm
@@ -62,7 +62,7 @@
;;
;; The list of accounts which are to be placed in the
;; gnc:html-acct-table object can be controled with the
-;; gnc:make-html-acct-table/accts, gnc:make-html-acct-table/accts/env,
+;; gnc:make-html-acct-table/accts, gnc:make-html-acct-table/env/accts,
;; and gnc:html-table-add-accts! functions.
;;
;; The gnc:html-acct-table parameters, set with
@@ -171,6 +171,27 @@
;; account having a balance of zero. otherwise, a row will be
;; generated for the account.
;;
+;; balance-mode: 'pre-adjusting 'pre-closing 'post-closing
+;;
+;; indicates whether or not to ignore adjusting/closing
+;; entries when computing account balances. 'pre-closing
+;; ignores only closing entries. 'pre-adjusting also ignores
+;; adjusting entries. 'post-closing counts all entries.
+;;
+;; adjusting-pattern: alist of 'str 'cased 'regexp
+;;
+;; a pattern alist, as accepted by
+;; gnc:account-get-trans-type-balance-interval, matching
+;; adjusting transactions to be ignored when balance-mode is
+;; 'pre-adjusting.
+;;
+;; closing-pattern: alist of 'str 'cased 'regexp
+;;
+;; a pattern alist, as accepted by
+;; gnc:account-get-trans-type-balance-interval, matching
+;; closing transactions to be ignored when balance-mode is
+;; 'pre-closing.
+;;
;; account-type: unimplemented
;; account-class: unimplemented
;; row-thunk: unimplemented (for gnc:html-acct-table-render)
@@ -507,6 +528,21 @@
'show-leaf-acct)
))
(label-mode (or (get-val env 'account-label-mode) 'anchor))
+ (balance-mode (or (get-val env 'balance-mode) 'post-closing))
+ (closing-pattern (or (get-val env 'closing-pattern)
+ (list
+ (list 'str (N_ "Closing Entries"))
+ (list 'cased #f)
+ (list 'regexp #f)
+ )
+ ))
+ (adjusting-pattern (or (get-val env 'adjusting-pattern)
+ (list
+ (list 'str (N_ "Adjusting Entries"))
+ (list 'cased #f)
+ (list 'regexp #f)
+ )
+ ))
;; local variables
(toplvl-accts (gnc:group-get-account-list (gnc:get-current-group)))
(acct-depth-reached 0)
@@ -522,14 +558,45 @@
)
)
- ;; the following two functions were lifted directly
- ;; from html-utilities.scm
+ ;; the following function was adapted from html-utilities.scm
(define (my-get-balance-nosub account start-date end-date)
- (if start-date
- (gnc:account-get-comm-balance-interval
- account start-date end-date #f)
- (gnc:account-get-comm-balance-at-date
- account end-date #f)))
+ (let* ((post-closing-bal
+ (if start-date
+ (gnc:account-get-comm-balance-interval
+ account start-date end-date #f)
+ (gnc:account-get-comm-balance-at-date
+ account end-date #f)))
+ (closing (lambda(a)
+ (gnc:account-get-trans-type-balance-interval
+ (list account) closing-pattern
+ start-date end-date)
+ )
+ )
+ (adjusting (lambda(a)
+ (gnc:account-get-trans-type-balance-interval
+ (list account) adjusting-pattern
+ start-date end-date)
+ )
+ )
+ )
+ (or (and (equal? balance-mode 'post-closing) post-closing-bal)
+ (and (equal? balance-mode 'pre-closing)
+ (let* ((closing-amt (closing account))
+ )
+ (post-closing-bal 'minusmerge closing-amt #f)
+ post-closing-bal)
+ )
+ (and (equal? balance-mode 'pre-adjusting)
+ (let* ((closing-amt (closing account))
+ (adjusting-amt (adjusting account))
+ )
+ (post-closing-bal 'minusmerge closing-amt #f)
+ (post-closing-bal 'minusmerge adjusting-amt #f)
+ post-closing-bal)
+ )
+ )
+ )
+ )
;; Additional function that includes the subaccounts as
;; well. Note: It is necessary to define this here (instead of
@@ -741,10 +808,12 @@
(define (gnc:html-acct-table-get-cell acct-table row col)
;; we'll only ever store one object in an html-table-cell
;; returns the first object stored in that cell
- (car (gnc:html-table-cell-data
- (gnc:html-table-get-cell
- (gnc:_html-acct-table-matrix_ acct-table)
- row (+ col 1)))))
+ (let* ((cell (gnc:html-table-get-cell
+ (gnc:_html-acct-table-matrix_ acct-table)
+ row (+ col 1))))
+ (and cell (car (gnc:html-table-cell-data cell)))
+ )
+ )
(define (gnc:html-acct-table-set-cell! acct-table row col obj)
(gnc:html-table-set-cell!
@@ -753,7 +822,8 @@
obj))
(define (gnc:html-acct-table-get-row-env acct-table row)
- (gnc:html-acct-table-get-cell acct-table row -1))
+ (gnc:html-acct-table-get-cell acct-table row -1)
+ )
(define (gnc:html-acct-table-set-row-env! acct-table row env)
(gnc:html-acct-table-set-cell! acct-table row -1 env))
@@ -888,21 +958,6 @@
table)
)
-(define (gnc:uniform-commodity? amt report-commodity)
- ;; function to see if the commodity-collector amt
- ;; contains any foreign commodities
- (lambda (amt)
- (let ((elts (gnc:commodity-collector-commodity-count amt))
- )
- (or (equal? elts 0)
- (and (equal? elts 1)
- (gnc:commodity-collector-contains-commodity?
- amt report-commodity)
- )
- )
- )
- ))
-
;;
;; This function adds all the lines from a gnc:html-acct-table to a
;; gnc:html-table in "labeled amount" form.
--- /dev/null
+++ src/count.gplot
@@ -0,0 +1,26 @@
+#
+# file: count.gplot
+# function: plot the number of lines of code in gnucash as function of date
+# To generate the graph, say "gnuplot count.gplot" at the command line
+#
+# history: created by Linas Vepstas July 2004
+#
+# set term x11
+# set term pbm
+# set term gif size 400,300
+set term pbm medium color
+set out 'count.png'
+set data style linespoints
+set xdata time
+set timefmt "%d/%m/%Y"
+# set format x "%m/%y"
+set format x "%Y"
+set xrange ["01/09/1997":"01/12/2003"]
+set title "Number of Lines of code in GnuCash"
+set key right
+set xlabel "Year"
+set logscale y
+set ylabel "KLOC\nLogarithmic Scale"
+plot "count.dat" using 1:2 title "kloc"
+
+# pause 1000
--- /dev/null
+++ src/count.dat
@@ -0,0 +1,33 @@
+#
+# file: count.dat
+#
+# Raw data for the number of KLOC of code in gnucash,
+# as a function of date. Taken from the web page
+# http://www.gnucash.org/en/sizing.phtml
+# format: day/month/year <tab> KLOC
+# plot this by saying "gnuplot count.gplot" at the command line
+#
+# xacc-0.9 Sept 97
+1/9/1997 8.8
+# xacc-0.9w Dec 97
+1/12/1997 16.2
+# xacc-1.0.17 Feb 98
+1/2/1998 18.3
+# gnucash-1.1.15 Aug 98
+1/8/1998 34.7
+# gnucash-1.2.2 Aug 99
+1/8/1999 39.0
+# gnucash-1.3.6 April 2000
+1/4/2000 95.1
+# gnucash-1.4.6 Sept 2000
+# 1/9/2000 101.9
+# gnucash-1.4.12 April 2001
+# 1/4/2001 108.2
+# gnucash-1.5.2 Sept 2000
+1/9/2000 114.2
+# gnucash-1.6.0 June 2001
+1/6/2001 193.9
+# gnucash-1.7.2 November 2002
+1/11/2002 297.1
+# gnucash-1.8.4 June 2003
+1/6/2003 385.5
Index: engine.texinfo
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/doc/design/engine.texinfo,v
retrieving revision 1.48.4.1
retrieving revision 1.48.4.2
diff -Lsrc/doc/design/engine.texinfo -Lsrc/doc/design/engine.texinfo -u -r1.48.4.1 -r1.48.4.2
--- src/doc/design/engine.texinfo
+++ src/doc/design/engine.texinfo
@@ -42,25 +42,24 @@
@section Introduction
Splits (@pxref{Splits}), or "Ledger Entries" are the fundamental
-accounting units. Each Split consists of a quantity (number of dollar
-bills, number of shares, etc.), the value of that quantity expressed in
-a (possibly) different currency than the quantity, a Memo, a pointer to
+accounting units. Each Split consists of an amount (number of dollar
+bills, number of shares, etc.), the value of that amount expressed in
+a (possibly) different currency than the amount, a Memo, a pointer to
the parent Transaction, a pointer to the debited Account, a reconciled
flag and timestamp, an "Action" field, and a key-value frame which can
store arbitrary data (@pxref{Key-Value Pair Frames}).
Transactions (@pxref{Transactions}) embody the notion of "double entry"
-accounting. A Transaction consists of a date, a description, a number, a
-list of one or more Splits, and a key-value frame. When double-entry
-rules are enforced, the total value of the splits is zero. Note that if
-there is just one split, its value must be zero for double-entry
-accounting; this used to be used for storing prices, but with the advent
-of the Price DB, this is no longer the case. If there are two splits,
+accounting. A Transaction consists of a date, a description, an ID number, a
+list of one or more Splits, and a key-value frame. The transaction
+also specifies the currency with which all of the splits will be
+valued. When double-entry rules are enforced, the total value of
+the splits are zero. If there are only two splits,
then the value of one must be positive, the other negative: this denotes
that one account is debited, and another is credited by an equal
-amount. Positive Split values are 'debits' and negative Split values are
-'credits'. Ensuring the Splits to 'add up' to zero causes a double-entry
-accounting system to always balance.
+amount. By forcing the value of the splits to always 'add up' to
+zero, we can gaurentee that the balances of the accounts are always
+correctly balanced.
The engine does not enforce double-entry accounting, but provides an API
to enable user-code to find unbalanced transactions and 'repair' them so
@@ -85,13 +84,10 @@
A Split can belong to at most one Account. Besides merely containing a
list of Splits, the Account structure also give the Account a name, a
code number, description and notes fields, a key-value frame, a pointer
-to the currency that is used for all splits in this account, and a
-pointer to the "security" used for all splits in this account. The
-"security" can be the name of a stock (e.g. "IBM", "McDonald's"), or
-another currency (e.g. "USD", "GBP"). The security is used during
-Transaction balancing to enable trading between accounts denominated in
-different currencies, or to, for example, move stocks from one Account
-to another.
+to the commodity that is used for all splits in this account. The
+commodity can be the name of anything traded and tradable: a stock
+(e.g. "IBM", "McDonald's"), a currency (e.g. "USD", "GBP"), or
+anything added to the commodity table.
Accounts can be arranged in a hierarchical tree. The nodes of the tree
are called "Account Groups" (@pxref{Account Groups}). By accounting
Index: advanced-portfolio.scm
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/report/standard-reports/advanced-portfolio.scm,v
retrieving revision 1.5.2.2
retrieving revision 1.5.2.3
diff -Lsrc/report/standard-reports/advanced-portfolio.scm -Lsrc/report/standard-reports/advanced-portfolio.scm -u -r1.5.2.2 -r1.5.2.3
--- src/report/standard-reports/advanced-portfolio.scm
+++ src/report/standard-reports/advanced-portfolio.scm
@@ -41,6 +41,7 @@
(define optname-price-source (N_ "Price Source"))
(define optname-shares-digits (N_ "Share decimal places"))
(define optname-zero-shares (N_ "Include accounts with no shares"))
+(define optname-include-gains (N_ "Include gains and losses"))
(define (options-generator)
(let* ((options (gnc:new-options))
@@ -78,6 +79,13 @@
"e" (N_ "The number of decimal places to use for share numbers") 2
0 6 0 1))
+ (gnc:register-option
+ options
+ (gnc:make-simple-boolean-option
+ gnc:pagename-general optname-include-gains "f"
+ (N_ "Include splits with no shares for calculating money-in and money-out")
+ #f))
+
;; Account tab
(add-option
(gnc:make-account-list-option
@@ -127,7 +135,7 @@
(string=? (gnc:split-get-guid s1) (gnc:split-get-guid s2)))
(define (table-add-stock-rows table accounts to-date
- currency price-fn exchange-fn include-empty
+ currency price-fn exchange-fn include-empty include-gains
total-value total-moneyin total-moneyout
total-gain)
@@ -178,7 +186,7 @@
((same-split? s split)
;; (gnc:debug "amount" (gnc:numeric-to-double (gnc:split-get-amount s)) )
(cond
- ((not (gnc:numeric-zero-p (gnc:split-get-amount s)))
+ ((or include-gains (not (gnc:numeric-zero-p (gnc:split-get-amount s))))
(unitscoll 'add commodity (gnc:split-get-amount s)) ;; Is the stock transaction?
(if (< 0 (gnc:numeric-to-double
(gnc:split-get-amount s)))
@@ -282,6 +290,8 @@
gnc:optname-reportname))
(include-empty (get-option gnc:pagename-accounts
optname-zero-shares))
+ (include-gains (get-option gnc:pagename-general
+ optname-include-gains))
(total-value (gnc:make-commodity-collector))
(total-moneyin (gnc:make-commodity-collector))
@@ -330,7 +340,7 @@
(table-add-stock-rows
table accounts to-date currency price-fn exchange-fn
- include-empty total-value total-moneyin total-moneyout total-gain)
+ include-empty include-gains total-value total-moneyin total-moneyout total-gain)
(gnc:html-table-append-row/markup!
table
Index: transaction.scm
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/report/standard-reports/transaction.scm,v
retrieving revision 1.15.4.2
retrieving revision 1.15.4.3
diff -Lsrc/report/standard-reports/transaction.scm -Lsrc/report/standard-reports/transaction.scm -u -r1.15.4.2 -r1.15.4.3
--- src/report/standard-reports/transaction.scm
+++ src/report/standard-reports/transaction.scm
@@ -508,18 +508,13 @@
(gnc:make-account-list-option
gnc:pagename-accounts (N_ "Report Accounts")
"a" (N_ "Report on these accounts")
- (lambda ()
- ;; FIXME : gnc:get-current-accounts disappeared.
- (let ((current-accounts '())
- (num-accounts (gnc:group-get-num-accounts
- (gnc:get-current-group)))
- (first-account (gnc:group-get-account
- (gnc:get-current-group) 0)))
- (cond ((not (null? current-accounts))
- (list (car current-accounts)))
- ((> num-accounts 0) (list first-account))
- (else ()))))
- #f #t))
+ ;; select, by default, all accounts...
+ (lambda ()
+ (gnc:filter-accountlist-type
+ '(bank cash credit asset liability stock mutual-fund currency
+ payable receivable equity income expense)
+ (gnc:group-get-subaccounts (gnc:get-current-group))))
+ #f #t))
(gnc:register-trep-option
(gnc:make-account-list-option
@@ -908,9 +903,9 @@
(list
(gnc:make-html-table-cell/size
1 width (gnc:make-html-text (gnc:html-markup-hr)))))
-
- (render-grand-total table width total-collector export?))
-
+ (if (gnc:option-value (gnc:lookup-option options "Display" "Totals"))
+ (render-grand-total table width total-collector export?)))
+
(let* ((current (car splits))
(current-row-style (if multi-rows? def:normal-row-style
(if odd-row? def:normal-row-style
@@ -1315,7 +1310,8 @@
(_ "No matching transactions found"))
(gnc:html-markup-p
(_ "No transactions were found that \
-match the given time interval and account selection.")))
+match the time interval and account selection specified \
+in the Options panel.")))
(gnc:html-document-add-object! document p))))
;; error condition: no accounts specified
Index: balance-sheet.scm
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/report/standard-reports/balance-sheet.scm,v
retrieving revision 1.11.4.3
retrieving revision 1.11.4.4
diff -Lsrc/report/standard-reports/balance-sheet.scm -Lsrc/report/standard-reports/balance-sheet.scm -u -r1.11.4.3 -r1.11.4.4
--- src/report/standard-reports/balance-sheet.scm
+++ src/report/standard-reports/balance-sheet.scm
@@ -18,18 +18,15 @@
;; default) accounts representative of current & fixed assets &
;; liabilities.
;;
-;; There are some gnc:html-acct-table options which remain unused,
-;; mostly because I don't know how to make drop-down option
-;; controls.
-;;
-;; This code makes the assumption that you want your equity
-;; statement to no more than daily resolution.
+;; This code makes the assumption that you want your balance
+;; sheet to no more than daily resolution.
;;
;; The Company Name field does not currently default to the name
;; in (gnc:get-current-book).
;;
;; Line & column alignments still do not conform with
;; textbook accounting practice (they're close though!).
+;; The 'canonically-tabbed option is currently broken.
;;
;; Progress bar functionality is currently mostly broken.
;;
@@ -101,13 +98,12 @@
(define opthelp-bottom-behavior
(N_ "Displays accounts which exceed the depth limit at the depth limit"))
-(define optname-show-parent-balance (N_ "Show any balance in parent accounts"))
-(define opthelp-show-parent-balance (N_ "Show any balance in parent accounts"))
-;; FIXME optname-show-parent-balance needs immediate/recursive/omit choices
-(define optname-show-parent-total (N_ "Show parent account subtotals"))
-(define opthelp-show-parent-total
- (N_ "Show account subtotals for all selected accounts having children"))
-;; FIXME optname-show-parent-total needs a 'canonically-tabbed choice
+(define optname-parent-balance-mode (N_ "Parent account balances"))
+(define opthelp-parent-balance-mode
+ (N_ "How to show any balance in parent accounts"))
+(define optname-parent-total-mode (N_ "Parent account subtotals"))
+(define opthelp-parent-total-mode
+ (N_ "How to show account subtotals for selected accounts having children"))
(define optname-show-zb-accts (N_ "Include accounts with zero total balances"))
(define opthelp-show-zb-accts
@@ -272,14 +268,36 @@
gnc:pagename-display optname-omit-zb-bals
"b" opthelp-omit-zb-bals #f))
;; what to show for non-leaf accounts
- (add-option
- (gnc:make-simple-boolean-option
- gnc:pagename-display optname-show-parent-balance
- "c" opthelp-show-parent-balance #t))
- (add-option
- (gnc:make-simple-boolean-option
- gnc:pagename-display optname-show-parent-total
- "d" opthelp-show-parent-total #f))
+ (add-option
+ (gnc:make-multichoice-option
+ gnc:pagename-display optname-parent-balance-mode
+ "c" opthelp-parent-balance-mode
+ 'immediate-bal
+ (list (vector 'immediate-bal
+ (N_ "Show Immediate Balance")
+ (N_ "Show only the balance in the parent account, excluding any subaccounts"))
+ (vector 'recursive-bal
+ (N_ "Recursive Balance")
+ (N_ "Include subaccounts in balance"))
+ (vector 'omit-bal
+ (N_ "Omit Balance")
+ (N_ "Do not show parent account balances")))))
+ (add-option
+ (gnc:make-multichoice-option
+ gnc:pagename-display optname-parent-total-mode
+ "d" opthelp-parent-total-mode
+ 'f
+ (list (vector 't
+ (N_ "Show subtotals")
+ (N_ "Show subtotals for selected accounts which have subaccounts"))
+ (vector 'f
+ (N_ "Do not show subtotals")
+ (N_ "Do not subtotal selected parent accounts"))
+ (vector 'canonically-tabbed
+ ;;(N_ "Subtotals indented text book style")
+ (N_ "Text book style (experimental)")
+ (N_ "Show parent account subtotals, indented per text book practice (experimental)")))))
+
;; some detailed formatting options
(add-option
(gnc:make-simple-boolean-option
@@ -325,7 +343,7 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; balance-sheet-renderer
;; set up the document and add the table
-;; then then return the document or, if
+;; then return the document or, if
;; requested, export it to a file
;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -362,10 +380,13 @@
optname-show-foreign))
(show-rates? (get-option pagename-commodities
optname-show-rates))
- (show-parent-balance? (get-option gnc:pagename-display
- optname-show-parent-balance))
- (show-parent-total? (get-option gnc:pagename-display
- optname-show-parent-total))
+ (parent-balance-mode (get-option gnc:pagename-display
+ optname-parent-balance-mode))
+ (parent-total-mode
+ (car
+ (assoc-ref '((t #t) (f #f) (canonically-tabbed canonically-tabbed))
+ (get-option gnc:pagename-display
+ optname-parent-total-mode))))
(show-zb-accts? (get-option gnc:pagename-display
optname-show-zb-accts))
(omit-zb-bals? (get-option gnc:pagename-display
@@ -409,7 +430,7 @@
;; (asset, liability, equity) have the same width.
(tree-depth (if (equal? depth-limit 'all)
(gnc:get-current-group-depth)
- depth-limit))
+ depth-limit))
;; exchange rates calculation parameters
(exchange-fn
(gnc:case-exchange-fn price-source report-commodity date-tp))
@@ -420,6 +441,7 @@
(define (add-subtotal-line table pos-label neg-label signed-balance)
(define allow-same-column-totals #t)
(let* ((neg? (and signed-balance
+ neg-label
(gnc:numeric-negative-p
(gnc:gnc-monetary-amount
(gnc:sum-collector-commodity
@@ -459,7 +481,7 @@
;;(gnc:warn "account names" liability-account-names)
(gnc:html-document-set-title!
- doc (string-append report-title " " company-name " "
+ doc (string-append company-name " " report-title " "
(gnc:print-date date-tp))
)
@@ -616,7 +638,7 @@
'summarize))
(list 'report-commodity report-commodity)
(list 'exchange-fn exchange-fn)
- (list 'parent-account-subtotal-mode show-parent-total?)
+ (list 'parent-account-subtotal-mode parent-total-mode)
(list 'zero-balance-mode (if show-zb-accts?
'show-leaf-acct
'omit-leaf-acct))
@@ -627,11 +649,7 @@
)
(set! params
(list
- (list 'parent-account-balance-mode
- (if show-parent-balance?
- 'immediate-bal
- 'omit-bal
- ))
+ (list 'parent-account-balance-mode parent-balance-mode)
(list 'zero-balance-display-mode (if omit-zb-bals?
'omit-balance
'show-balance))
--- /dev/null
+++ src/report/standard-reports/trial-balance.scm
@@ -0,0 +1,1154 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; trial-balance.scm: trial balance and work sheet
+;; By David Montenegro <sunrise2000 at comcast.net>
+;;
+;; Prepares a trial balance of your books.
+;; Optionally prepares a complete work sheet.
+;;
+;; N.B.: Since GnuCash ensures that all your debits and credits
+;; balance, preparing a Trial Balance isn't technically necessary for
+;; GnuCash users. This report is included primarily for pedagogical
+;; and corroborative purposes.
+;;
+;; BUGS:
+;;
+;; This code makes the assumption that you want your trial
+;; balance to no more than daily resolution.
+;;
+;; The Company Name field does not currently default to the name
+;; in (gnc:get-current-book).
+;;
+;; Progress bar functionality is currently mostly broken.
+;;
+;; Unsure if the multi-currency support is correct.
+;;
+;; The variables in this code could use more consistent naming.
+;;
+;; See also any "FIXME"s in the code.
+;;
+;; Largely borrowed from balance-sheet.scm By Robert Merkel <rgmerk at mira.net>
+;;
+;; Largely borrowed from pnl.scm by:
+;; Christian Stimming <stimming at tu-harburg.de>
+;;
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 2 of
+;; the License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, contact:
+;;
+;; Free Software Foundation Voice: +1-617-542-5942
+;; 59 Temple Place - Suite 330 Fax: +1-617-542-2652
+;; Boston, MA 02111-1307, USA gnu at gnu.org
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(define-module (gnucash report trial-balance))
+(use-modules (gnucash main)) ;; FIXME: delete after we finish modularizing.
+(use-modules (ice-9 slib))
+(use-modules (gnucash gnc-module))
+
+(gnc:module-load "gnucash/report/report-system" 0)
+
+(define reportname (N_ "Trial Balance"))
+
+;; define all option's names and help text so that they are properly
+;; defined in *one* place.
+(define optname-report-title (N_ "Report Title"))
+(define opthelp-report-title (N_ "Title for this report"))
+
+(define optname-party-name (N_ "Company name"))
+(define opthelp-party-name (N_ "Name of company/individual"))
+
+(define optname-start-date (N_ "Start of Adjusting/Closing"))
+(define opthelp-start-date
+ (N_ "The earliest date Adjusting/Closing entries were made for this period"))
+(define optname-end-date (N_ "Date of Report"))
+(define opthelp-end-date (N_ "Trial Balance/Work Sheet as-of date"))
+(define optname-report-variant (N_ "Report variation"))
+(define opthelp-report-variant (N_ "Kind of trial balance to generate"))
+;; FIXME this needs an indent option
+
+(define optname-accounts (N_ "Accounts to include"))
+(define opthelp-accounts
+ (N_ "Report on these accounts"))
+(define optname-depth-limit (N_ "Levels of Subaccounts"))
+(define opthelp-depth-limit
+ (N_ "Maximum number of levels in the account tree displayed"))
+
+(define pagename-merchandising (N_ "Merchandising"))
+(define optname-gross-adjustment-accounts (N_ "Gross adjustment accounts"))
+(define opthelp-gross-adjustment-accounts
+ (N_ "Do not net, but show gross debit/credit adjustments to these accounts. Merchandising businesses will normally select their inventory accounts here."))
+(define optname-income-summary-accounts (N_ "Income summary accounts"))
+(define opthelp-income-summary-accounts
+ (N_ "Adjustments made to these accounts are gross adjusted (see above) in the Adjustments, Adjusted Trial Balance, and Income Statement columns. Mostly useful for merchandising businesses."))
+
+(define pagename-entries (N_ "Entries"))
+(define optname-adjusting-pattern (N_ "Adjusting Entries pattern"))
+(define opthelp-adjusting-pattern
+ (N_ "Any text in the Description column which identifies adjusting entries"))
+(define optname-adjusting-casing
+ (N_ "Adjusting Entries pattern is case-sensitive"))
+(define opthelp-adjusting-casing
+ (N_ "Causes the Adjusting Entries Pattern match to be case-sensitive"))
+(define optname-adjusting-regexp
+ (N_ "Adjusting Entries Pattern is regular expression"))
+(define opthelp-adjusting-regexp
+ (N_ "Causes the Adjusting Entries Pattern to be treated as a regular expression"))
+
+(define optname-closing-pattern (N_ "Closing Entries pattern"))
+(define opthelp-closing-pattern
+ (N_ "Any text in the Description column which identifies closing entries"))
+(define optname-closing-casing
+ (N_ "Closing Entries pattern is case-sensitive"))
+(define opthelp-closing-casing
+ (N_ "Causes the Closing Entries Pattern match to be case-sensitive"))
+(define optname-closing-regexp
+ (N_ "Closing Entries Pattern is regular expression"))
+(define opthelp-closing-regexp
+ (N_ "Causes the Closing Entries Pattern to be treated as a regular expression"))
+
+;; FIXME: this option doesn't produce a correct work sheet when
+;; selected after closing... it omits adjusted temporary accounts
+;;
+;; the fix for this really should involve passing thunks to
+;; gnc:make-html-acct-table
+(define optname-show-zb-accts (N_ "Include accounts with zero total balances"))
+(define opthelp-show-zb-accts
+ (N_ "Include accounts with zero total (recursive) balances in this report"))
+
+(define optname-account-links (N_ "Display accounts as hyperlinks"))
+(define opthelp-account-links (N_ "Shows each account in the table as a hyperlink to its register window"))
+
+(define pagename-commodities (N_ "Commodities"))
+(define optname-report-commodity (N_ "Report's currency"))
+(define optname-price-source (N_ "Price Source"))
+(define optname-show-foreign (N_ "Show Foreign Currencies"))
+(define opthelp-show-foreign
+ (N_ "Display any foreign currency amount in an account"))
+(define optname-show-rates (N_ "Show Exchange Rates"))
+(define opthelp-show-rates (N_ "Show the exchange rates used"))
+
+;; options generator
+(define (trial-balance-options-generator)
+ (let* ((options (gnc:new-options))
+ (add-option
+ (lambda (new-option)
+ (gnc:register-option options new-option))))
+
+ (add-option
+ (gnc:make-string-option
+ (N_ "General") optname-report-title
+ "a" opthelp-report-title reportname))
+ (add-option
+ (gnc:make-string-option
+ (N_ "General") optname-party-name
+ "b" opthelp-party-name (N_ "")))
+ ;; this should default to company name in (gnc:get-current-book)
+
+ ;; the period over which to collect adjusting/closing entries and
+ ;; date at which to report the balance
+ (gnc:options-add-date-interval!
+ options gnc:pagename-general
+ optname-start-date optname-end-date "c")
+
+ (add-option
+ (gnc:make-multichoice-option
+ gnc:pagename-general optname-report-variant
+ "d" opthelp-report-variant
+ 'current
+ (list (vector 'current
+ (N_ "Current Trial Balance")
+ (N_ "Uses the exact balances in the general ledger"))
+ (vector 'pre-adj
+ (N_ "Pre-adjustment Trial Balance")
+ (N_ "Ignores Adjusting/Closing entries"))
+ (vector 'work-sheet
+ (N_ "Work Sheet")
+ (N_ "Creates a complete end-of-period work sheet")))))
+
+ ;; accounts to work on
+ (add-option
+ (gnc:make-account-list-option
+ gnc:pagename-accounts optname-accounts
+ "a"
+ opthelp-accounts
+ (lambda ()
+ (gnc:filter-accountlist-type
+ '(bank cash credit asset liability stock mutual-fund currency
+ payable receivable equity income expense)
+ (gnc:group-get-subaccounts (gnc:get-current-group))))
+ #f #t))
+ (gnc:options-add-account-levels!
+ options gnc:pagename-accounts optname-depth-limit
+ "b" opthelp-depth-limit 1)
+
+ ;; options for merchandising business work sheets
+ (add-option
+ (gnc:make-account-list-option
+ pagename-merchandising optname-gross-adjustment-accounts
+ "c"
+ opthelp-gross-adjustment-accounts
+ (lambda ()
+ ;; Here, it would be useful to have an inventory account type.
+ ;; Lacking that, just select no accounts by default.
+ '()
+ )
+ #f #t))
+ (add-option
+ (gnc:make-account-list-option
+ pagename-merchandising optname-income-summary-accounts
+ "d"
+ opthelp-income-summary-accounts
+ (lambda ()
+ '()
+ )
+ #f #t))
+
+ ;; all about currencies
+ (gnc:options-add-currency!
+ options pagename-commodities
+ optname-report-commodity "a")
+
+ (gnc:options-add-price-source!
+ options pagename-commodities
+ optname-price-source "b" 'weighted-average)
+
+ (add-option
+ (gnc:make-simple-boolean-option
+ pagename-commodities optname-show-foreign
+ "c" opthelp-show-foreign #f))
+
+ (add-option
+ (gnc:make-simple-boolean-option
+ pagename-commodities optname-show-rates
+ "d" opthelp-show-rates #f))
+
+ ;; adjusting/closing entry match criteria
+ ;;
+ ;; N.B.: transactions really should have a field where we can put
+ ;; transaction types like "Adjusting/Closing/Correcting Entries"
+ (add-option
+ (gnc:make-string-option
+ pagename-entries optname-adjusting-pattern
+ "a" opthelp-adjusting-pattern (N_ "Adjusting Entries")))
+ (add-option
+ (gnc:make-simple-boolean-option
+ pagename-entries optname-adjusting-casing
+ "b" opthelp-adjusting-casing #f))
+ (add-option
+ (gnc:make-simple-boolean-option
+ pagename-entries optname-adjusting-regexp
+ "c" opthelp-adjusting-regexp #f))
+ (add-option
+ (gnc:make-string-option
+ pagename-entries optname-closing-pattern
+ "d" opthelp-closing-pattern (N_ "Closing Entries")))
+ (add-option
+ (gnc:make-simple-boolean-option
+ pagename-entries optname-closing-casing
+ "e" opthelp-closing-casing #f))
+ (add-option
+ (gnc:make-simple-boolean-option
+ pagename-entries optname-closing-regexp
+ "f" opthelp-closing-regexp #f))
+
+ ;; what to show for zero-balance accounts
+ ;;(add-option
+ ;; (gnc:make-simple-boolean-option
+ ;; gnc:pagename-display optname-show-zb-accts
+ ;; "a" opthelp-show-zb-accts #t))
+
+ ;; some detailed formatting options
+ (add-option
+ (gnc:make-simple-boolean-option
+ gnc:pagename-display optname-account-links
+ "e" opthelp-account-links #t))
+
+ ;; Set the accounts page as default option tab
+ (gnc:options-set-default-section options gnc:pagename-display)
+
+ options))
+
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; trial-balance-renderer
+;; set up the document and add the table
+;; then then return the document or, if
+;; requested, export it to a file
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(define (trial-balance-renderer report-obj choice filename)
+ (define (get-option pagename optname)
+ (gnc:option-value
+ (gnc:lookup-option
+ (gnc:report-options report-obj) pagename optname)))
+ (define forever-ago (cons 0 0))
+
+ (gnc:report-starting reportname)
+
+ ;; get all option's values
+ (let* (
+ (report-title (get-option gnc:pagename-general optname-report-title))
+ (company-name (get-option gnc:pagename-general optname-party-name))
+ (start-date-printable (gnc:date-option-absolute-time
+ (get-option gnc:pagename-general
+ optname-start-date)))
+ (start-date-tp (gnc:timepair-end-day-time
+ (gnc:timepair-previous-day start-date-printable)))
+ (end-date-tp (gnc:timepair-end-day-time
+ (gnc:date-option-absolute-time
+ (get-option gnc:pagename-general
+ optname-end-date))))
+ (report-variant (get-option gnc:pagename-general
+ optname-report-variant))
+ (accounts (get-option gnc:pagename-accounts
+ optname-accounts))
+ (ga-accounts (get-option pagename-merchandising
+ optname-gross-adjustment-accounts))
+ (is-accounts (get-option pagename-merchandising
+ optname-income-summary-accounts))
+ (depth-limit (get-option gnc:pagename-accounts
+ optname-depth-limit))
+ (adjusting-str (get-option pagename-entries
+ optname-adjusting-pattern))
+ (adjusting-cased (get-option pagename-entries
+ optname-adjusting-casing))
+ (adjusting-regexp (get-option pagename-entries
+ optname-adjusting-regexp))
+ (closing-str (get-option pagename-entries
+ optname-closing-pattern))
+ (closing-cased (get-option pagename-entries
+ optname-closing-casing))
+ (closing-regexp (get-option pagename-entries
+ optname-closing-regexp))
+ (report-commodity (get-option pagename-commodities
+ optname-report-commodity))
+ (price-source (get-option pagename-commodities
+ optname-price-source))
+ (show-fcur? (get-option pagename-commodities
+ optname-show-foreign))
+ (show-rates? (get-option pagename-commodities
+ optname-show-rates))
+ ;;(show-zb-accts? (get-option gnc:pagename-display
+ ;; optname-show-zb-accts))
+ (show-zb-accts? #t) ;; see FIXME above
+ (use-links? (get-option gnc:pagename-display
+ optname-account-links))
+ (indent 0)
+
+ ;; decompose the account list
+ (split-up-accounts (gnc:decompose-accountlist accounts))
+ (asset-accounts
+ (assoc-ref split-up-accounts 'asset))
+ (liability-accounts
+ (assoc-ref split-up-accounts 'liability))
+ (equity-accounts
+ (assoc-ref split-up-accounts 'equity))
+ (income-expense-accounts
+ (append (assoc-ref split-up-accounts 'income)
+ (assoc-ref split-up-accounts 'expense)))
+ ;; (all-accounts (map (lambda (X) (cadr X)) split-up-accounts))
+ ;; ^ will not do what we want
+ (all-accounts
+ (append asset-accounts liability-accounts
+ equity-accounts income-expense-accounts))
+
+ ;; same for gross adjustment accounts...
+ (split-up-ga-accounts (gnc:decompose-accountlist ga-accounts))
+ (all-ga-accounts
+ (append (assoc-ref split-up-ga-accounts 'asset)
+ (assoc-ref split-up-ga-accounts 'liability)
+ (assoc-ref split-up-ga-accounts 'equity)
+ (assoc-ref split-up-ga-accounts 'income)
+ (assoc-ref split-up-ga-accounts 'expense)))
+ (split-up-is-accounts (gnc:decompose-accountlist is-accounts))
+
+ ;; same for income statement accounts...
+ (all-is-accounts
+ (append (assoc-ref split-up-is-accounts 'asset)
+ (assoc-ref split-up-is-accounts 'liability)
+ (assoc-ref split-up-is-accounts 'equity)
+ (assoc-ref split-up-is-accounts 'income)
+ (assoc-ref split-up-is-accounts 'expense)))
+
+ (doc (gnc:make-html-document))
+ ;; exchange rates calculation parameters
+ (exchange-fn
+ (gnc:case-exchange-fn price-source report-commodity end-date-tp))
+ (terse-period? #t)
+ (period-for (if terse-period?
+ (string-append " " (N_ "for Period"))
+ (string-append
+ ", "
+ (gnc:print-date start-date-printable) " "
+ (N_ "to") " "
+ (gnc:print-date end-date-tp)
+ )))
+ )
+
+ (gnc:html-document-set-title!
+ doc (if (equal? report-variant 'current)
+ (sprintf #f (string-append "%s %s %s")
+ company-name report-title
+ (gnc:print-date end-date-tp))
+ (sprintf #f (string-append "%s %s "
+ (N_ "For Period Covering")
+ " %s "
+ (N_ "to")
+ " %s")
+ company-name report-title
+ (gnc:print-date start-date-printable)
+ (gnc:print-date end-date-tp))
+ )
+ )
+
+ (if (null? accounts)
+
+ ;; error condition: no accounts specified
+ ;; is this *really* necessary??
+ ;; i'd be fine with an all-zero trial balance
+ ;; that would, technically, be correct....
+ (gnc:html-document-add-object!
+ doc
+ (gnc:html-make-no-account-warning
+ reportname (gnc:report-id report-obj)))
+
+ ;; Get all the balances for each account group.
+ (let* ((build-table (gnc:make-html-table))
+ (acct-table #f)
+ (debit-tot (gnc:make-commodity-collector))
+ (credit-tot (gnc:make-commodity-collector))
+ (unrealized-gain-collector #f)
+ (neg-unrealized-gain-collector #f)
+ (book-balance #f) ;; assets - liabilities - equity, norm 0
+ (table-env #f) ;; parameters for :make-
+ (account-cols #f)
+ (indented-depth #f)
+ (header-rows 0)
+ (adj-debits (gnc:make-commodity-collector))
+ (adj-credits (gnc:make-commodity-collector))
+ (atb-debits (gnc:make-commodity-collector))
+ (atb-credits (gnc:make-commodity-collector))
+ (is-debits (gnc:make-commodity-collector))
+ (is-credits (gnc:make-commodity-collector))
+ (bs-debits (gnc:make-commodity-collector))
+ (bs-credits (gnc:make-commodity-collector))
+ )
+
+ ;; Wrapper to call gnc:html-table-add-labeled-amount-line!
+ ;; with the proper arguments.
+ ;; (This is used to fill in the Trial Balance columns.)
+ (define (add-line table label signed-balance)
+ (let* ((entry (gnc:double-col
+ 'entry signed-balance
+ report-commodity exchange-fn show-fcur?))
+ (credit? (gnc:double-col
+ 'credit-q signed-balance
+ report-commodity exchange-fn show-fcur?))
+ )
+ (gnc:html-table-add-labeled-amount-line!
+ table
+ (+ account-cols 2)
+ "primary-subheading"
+ #f
+ label indented-depth 1 "text-cell"
+ entry
+ (+ account-cols (if credit? 1 0)) 1 "number-cell"
+ )
+ ;; update the running totals
+ (if credit?
+ (credit-tot 'minusmerge signed-balance #f)
+ (debit-tot 'merge signed-balance #f)
+ )
+ )
+ )
+
+ (define (get-val alist key)
+ (let ((lst (assoc-ref alist key)))
+ (if lst (car lst) lst)))
+
+ (define pa-col 0) ;; pre-adjustments column
+ (define adj-col 1) ;; adjustments column
+ (define atb-col 2) ;; adjusted trial balance column
+ (define is-col 3) ;; income statement column
+ (define bs-col 4) ;; balance sheet column
+ (define bal-col 5) ;; for the current (general ledger) balance
+
+ (define (report-val amt)
+ (gnc:sum-collector-commodity
+ amt report-commodity exchange-fn)
+ )
+
+ ;; Returns a gnc:html-table-cell containing the absolute value
+ ;; of the given amount in the report commodity.
+ (define (tot-abs-amt-cell amt)
+ (let* ((neg-amt (gnc:make-commodity-collector))
+ (rv (report-val amt))
+ (neg? (gnc:numeric-negative-p
+ (gnc:gnc-monetary-amount rv)))
+ (cell #f)
+ )
+ (neg-amt 'minusmerge amt #f)
+ (set! cell
+ (gnc:make-html-table-cell/markup
+ "total-number-cell" (if neg? (report-val neg-amt) rv)))
+ (gnc:html-table-cell-set-style!
+ cell "total-number-cell"
+ 'attribute '("align" "right")
+ 'attribute '("valign" "top")
+ )
+ cell)
+ )
+
+ ;; set default cell alignment
+ (gnc:html-table-set-style!
+ build-table "td"
+ 'attribute '("align" "right")
+ 'attribute '("valign" "top")
+ )
+
+ (gnc:report-percent-done 4)
+ ;; sum any unrealized gains
+ ;;
+ ;; Hm... unrealized gains.... This is when you purchase
+ ;; something and its value increases/decreases (prior to
+ ;; your selling it) and you have to reflect that on your
+ ;; balance sheet.
+ ;;
+ ;; I *think* a decrease in the value of a liability or
+ ;; equity constitutes an unrealized loss. I'm unsure about
+ ;; that though....
+ ;;
+ (set! book-balance (gnc:make-commodity-collector))
+ (map (lambda (acct)
+ (book-balance
+ 'merge
+ (gnc:account-get-comm-balance-at-date acct end-date-tp #f)
+ #f)
+ )
+ all-accounts)
+ (set! unrealized-gain-collector (gnc:make-commodity-collector))
+ (let* ((weighted-fn
+ (gnc:case-exchange-fn 'weighted-average
+ report-commodity end-date-tp))
+
+ (value
+ (gnc:gnc-monetary-amount
+ (gnc:sum-collector-commodity book-balance
+ report-commodity
+ exchange-fn)))
+
+ (cost
+ (gnc:gnc-monetary-amount
+ (gnc:sum-collector-commodity book-balance
+ report-commodity
+ weighted-fn)))
+
+ (unrealized-gain (gnc:numeric-sub-fixed value cost)))
+
+ (unrealized-gain-collector 'add report-commodity unrealized-gain)
+ )
+ (set! neg-unrealized-gain-collector (gnc:make-commodity-collector))
+ (neg-unrealized-gain-collector 'minusmerge
+ unrealized-gain-collector
+ #f)
+ (set! table-env
+ (list
+ (list 'start-date #f)
+ (list 'end-date end-date-tp)
+ (list 'display-tree-depth
+ (if (integer? depth-limit) depth-limit #f))
+ (list 'depth-limit-behavior 'flatten)
+ (list 'report-commodity report-commodity)
+ (list 'exchange-fn exchange-fn)
+ (list 'parent-account-subtotal-mode #f)
+ (list 'zero-balance-mode (if show-zb-accts?
+ 'show-leaf-acct
+ 'omit-leaf-acct))
+ (list 'account-label-mode (if use-links?
+ 'anchor
+ 'name))
+ )
+ )
+
+ (set! acct-table
+ (gnc:make-html-acct-table/env/accts table-env all-accounts))
+
+ (gnc:report-percent-done 80)
+ (let* ((env (gnc:html-acct-table-get-row-env acct-table 0)))
+ (set! account-cols (get-val env 'account-cols))
+ )
+
+ ;; Workaround to force gtkhtml into displaying wide
+ ;; enough columns.
+ (let ((space
+ (make-list
+ (+ account-cols
+ (if (equal? report-variant 'work-sheet) 10 2))
+ " ")
+ ))
+ (gnc:html-table-append-row! build-table space)
+ (set! header-rows (+ header-rows 1))
+ )
+ ;; add the double-column headers if required
+ (if (equal? report-variant 'work-sheet)
+ (let* ((headings
+ (list
+ (N_ "TRIAL BALANCE")
+ (N_ "ADJUSTMENTS")
+ (N_ "ADJUSTED TRIAL BALANCE")
+ (N_ "INCOME STATEMENT")
+ (N_ "BALANCE SHEET")
+ ))
+ (parent-headings #f)
+ )
+ (set! parent-headings
+ (apply append
+ (map
+ (if gnc:colspans-are-working-right
+ (lambda (heading)
+ (list
+ (gnc:make-html-table-cell/size/markup
+ 1 2 "th" heading)
+ )
+ )
+ (lambda (heading)
+ (list
+ (gnc:make-html-table-cell/size/markup
+ 1 1 "th" heading)
+ (gnc:html-make-empty-cell)
+ )
+ )
+ )
+ headings)
+ )
+ )
+ (gnc:html-table-append-row!
+ build-table
+ (append
+ (if gnc:colspans-are-working-right
+ (list (gnc:make-html-table-cell/size 1 account-cols #f))
+ (gnc:html-make-empty-cells account-cols)
+ )
+ parent-headings)
+ )
+ (set! header-rows (+ header-rows 1))
+ )
+ )
+ ;; add the DEBIT/CREDIT headers
+ (let* ((debit-cell
+ (gnc:make-html-table-cell/markup
+ "th" (N_ "DEBIT")))
+ (credit-cell
+ (gnc:make-html-table-cell/markup
+ "th" (N_ "CREDIT")))
+ (row (append
+ (list (gnc:make-html-table-cell/markup
+ "total-label-cell" (N_ "Account Title")))
+ (gnc:html-make-empty-cells (- account-cols 1))
+ (list debit-cell)
+ (list credit-cell))
+ )
+ (ws-col 0)
+ )
+ (if (equal? report-variant 'work-sheet)
+ (let ((rownum 0)
+ (ws-cols 4)
+ )
+ (while (< rownum ws-cols)
+ (set! row (append row (list debit-cell credit-cell)))
+ (set! rownum (+ rownum 1))
+ )
+ )
+ )
+ (gnc:html-table-append-row!
+ build-table
+ row
+ )
+ (set! header-rows (+ header-rows 1))
+ )
+
+ ;; now, for each account, calculate all the column values
+ ;; and store them in the utility object...
+ ;;
+ ;; this handles merchandising (inventory and income summary)
+ ;; accounts specially. instead of storing a commodity collector,
+ ;; it stores a two-element list of commodity collectors:
+ ;; (list debit-collector credit-collector)
+ (let ((row 0)
+ (rows (gnc:html-acct-table-num-rows acct-table))
+ )
+ (while (< row rows)
+ (let* ((env
+ (gnc:html-acct-table-get-row-env acct-table row))
+ (acct (get-val env 'account))
+ (group (list acct))
+ (curr-bal (get-val env 'account-bal))
+ (closing
+ (gnc:account-get-trans-type-balance-interval
+ group
+ (list (list 'str closing-str)
+ (list 'cased closing-cased)
+ (list 'regexp closing-regexp)
+ )
+ start-date-tp end-date-tp
+ ))
+ (adjusting
+ (gnc:account-get-trans-type-balance-interval
+ group
+ (list (list 'str adjusting-str)
+ (list 'cased adjusting-cased)
+ (list 'regexp adjusting-regexp)
+ )
+ start-date-tp end-date-tp
+ ))
+ (is? (member acct all-is-accounts))
+ (ga-or-is? (or (member acct all-ga-accounts) is?))
+ (pos-adjusting
+ (and ga-or-is?
+ adjusting
+ (gnc:account-get-pos-trans-total-interval
+ group
+ (list (list 'str adjusting-str)
+ (list 'cased adjusting-cased)
+ (list 'regexp adjusting-regexp)
+ (list 'positive #t)
+ )
+ start-date-tp end-date-tp
+ )
+ ))
+ (neg-adjusting
+ (and pos-adjusting (gnc:make-commodity-collector)))
+ (pre-closing-bal (gnc:make-commodity-collector))
+ (pre-adjusting-bal (gnc:make-commodity-collector))
+ (atb #f) ;; adjusted trial balance
+ )
+
+ ;; +P_ADJ + -N_ADJ = xADJ. xADJ - +P_ADJ = -N_ADJ.
+ ;; That is, credit values are stored as such (negative).
+ (if neg-adjusting
+ (begin
+ (neg-adjusting 'merge adjusting #f)
+ (neg-adjusting 'minusmerge pos-adjusting #f)
+ ))
+
+ (pre-closing-bal 'merge curr-bal #f)
+ ;; remove closing entries
+ (pre-closing-bal 'minusmerge closing #f)
+ (pre-adjusting-bal 'merge pre-closing-bal #f)
+ ;; remove closing entries
+ (pre-adjusting-bal 'minusmerge adjusting #f)
+ ;; we now have a pre-adjusting-bal,
+ ;; pre-closing-bal, and curr-bal
+
+ (set! atb
+ ;; calculate the adjusted trial balance to use
+ ;; this depends on whether or not we are netting
+ ;; the atb value... so we check is?.
+ (if is?
+ (let* ((debit (gnc:make-commodity-collector))
+ (credit (gnc:make-commodity-collector))
+ )
+ (debit 'merge pos-adjusting #f)
+ (credit 'merge neg-adjusting #f)
+ (if (gnc:double-col
+ 'credit-q pre-adjusting-bal
+ report-commodity exchange-fn show-fcur?)
+ (credit 'merge pre-adjusting-bal #f)
+ (debit 'merge pre-adjusting-bal #f)
+ )
+ (list debit credit)
+ )
+ pre-closing-bal)
+ )
+
+ (gnc:html-acct-table-set-cell!
+ acct-table row pa-col pre-adjusting-bal)
+ (gnc:html-acct-table-set-cell!
+ acct-table row adj-col
+ (if ga-or-is?
+ (list pos-adjusting neg-adjusting)
+ adjusting)
+ )
+ (gnc:html-acct-table-set-cell!
+ acct-table row atb-col atb)
+ (gnc:html-acct-table-set-cell!
+ acct-table row
+ (if (or (gnc:account-is-inc-exp? acct) is?)
+ is-col bs-col)
+ atb
+ )
+ (gnc:html-acct-table-set-cell!
+ acct-table row bal-col curr-bal)
+
+ (set! row (+ row 1))
+ )
+ )
+ )
+
+ ;; next, set up the account tree and pre-adjustment balances
+ ;; (This fills in the Account Title and Trial Balance columns.)
+ (let ((row 0)
+ (rows (gnc:html-acct-table-num-rows acct-table)))
+ (while (< row rows)
+ (let* ((env
+ (gnc:html-acct-table-get-row-env acct-table row))
+ (account-bal
+ (gnc:html-acct-table-get-cell
+ acct-table
+ row
+ (get-val (list (list 'pre-adj pa-col)
+ (list 'work-sheet pa-col)
+ (list 'current bal-col)
+ )
+ report-variant)
+ ))
+ (label (get-val env 'account-label))
+ )
+ ;; yeah, i know, global vars are devil... so deal with it
+ (set! indented-depth (get-val env 'indented-depth))
+ (add-line build-table label account-bal)
+ )
+ (set! row (+ row 1))
+ )
+ )
+
+ ;; handle any unrealized gains
+ ;;
+ ;; we omit unrealized gains from the balance report, if
+ ;; zero, since they are not present on normal trial balances
+ (and (not (gnc:commodity-collector-allzero?
+ unrealized-gain-collector))
+ (let* ((ug-row (+ header-rows
+ (gnc:html-acct-table-num-rows
+ acct-table)))
+ )
+ (add-line
+ build-table (N_ "Unrealized Gains")
+ neg-unrealized-gain-collector)
+ ;; make table line wide enough
+ (gnc:html-table-set-cell!
+ build-table
+ ug-row
+ (+ account-cols 1)
+ #f)
+ (if (equal? report-variant 'work-sheet)
+ (let* ((credit? (gnc:double-col
+ 'credit-q neg-unrealized-gain-collector
+ report-commodity exchange-fn show-fcur?))
+ (entry (gnc:double-col
+ 'entry neg-unrealized-gain-collector
+ report-commodity exchange-fn show-fcur?))
+ )
+ ;; make table line wide enough
+ (gnc:html-table-set-cell!
+ build-table
+ ug-row
+ (+ account-cols (* 2 bs-col) 1)
+ #f)
+ (gnc:html-table-set-cell!
+ build-table
+ ug-row
+ (+ account-cols (* 2 atb-col) (if credit? 1 0))
+ entry)
+ (gnc:html-table-set-cell!
+ build-table
+ ug-row
+ (+ account-cols (* 2 bs-col) (if credit? 1 0))
+ entry)
+ (if credit?
+ (and (atb-credits 'minusmerge
+ neg-unrealized-gain-collector #f)
+ (bs-credits 'minusmerge
+ neg-unrealized-gain-collector #f))
+ (and (atb-debits 'merge
+ neg-unrealized-gain-collector #f)
+ (bs-debits 'merge
+ neg-unrealized-gain-collector #f))
+ )
+ )
+ )
+ )
+ )
+
+ ;;
+ ;; now, if requested, complete the worksheet
+ ;;
+ ;; to complete the worksheet, we mostly just have to dink
+ ;; around, reading acct-table, putting values in the right
+ ;; build-table cells... which is comparatively easy.
+ ;;
+ (if (equal? report-variant 'work-sheet)
+ (let ((row 0)
+ (rows (gnc:html-acct-table-num-rows acct-table))
+ (last-col #f)
+ (html-row #f)
+ )
+ (while (< row rows)
+ (map (lambda (colpair debit-coll credit-coll)
+ (set! html-row (+ row header-rows))
+ (let* ((bal
+ (gnc:html-acct-table-get-cell
+ acct-table
+ row
+ colpair))
+ (gross-bal? (list? bal))
+ (entry (and bal
+ (not gross-bal?)
+ (gnc:double-col
+ 'entry bal
+ report-commodity
+ exchange-fn
+ show-fcur?)))
+ (credit? (and bal
+ (or gross-bal?
+ (gnc:double-col
+ 'credit-q bal
+ report-commodity
+ exchange-fn
+ show-fcur?)
+ )
+ ))
+ (non-credit? (and bal
+ (or gross-bal?
+ (not credit?))
+ ))
+ (debit (or
+ (and gross-bal? (car bal))
+ (and non-credit? bal)
+ ))
+ (credit (or
+ (and gross-bal? (cadr bal))
+ (and credit? bal)
+ ))
+ (debit-entry
+ (and gross-bal?
+ (gnc:double-col
+ 'entry debit
+ report-commodity
+ exchange-fn
+ show-fcur?))
+ )
+ (credit-entry
+ (and gross-bal?
+ (gnc:double-col
+ 'entry credit
+ report-commodity
+ exchange-fn
+ show-fcur?))
+ )
+ (col (+ account-cols
+ (* 2 colpair)
+ (if non-credit? 0 1))
+ )
+ )
+ (gnc:html-table-set-cell!
+ build-table
+ html-row
+ col
+ (or entry debit-entry)
+ )
+ (if gross-bal?
+ (gnc:html-table-set-cell!
+ build-table
+ html-row
+ (+ col 1)
+ credit-entry
+ )
+ )
+ ;; update the corresponing running total
+ (and bal
+ (begin
+ (if credit?
+ (credit-coll 'minusmerge
+ (if gross-bal?
+ credit bal)
+ #f)
+ )
+ (if non-credit?
+ (debit-coll 'merge
+ (if gross-bal?
+ debit bal)
+ #f)
+ )
+ )
+ )
+ )
+ )
+ (list adj-col atb-col is-col bs-col)
+ (list adj-debits atb-debits
+ is-debits bs-debits)
+ (list adj-credits atb-credits
+ is-credits bs-credits)
+ )
+ ;; make sure the row extends to the final column
+ (set! last-col (+ account-cols (* 2 bs-col) 1))
+ (or
+ (gnc:html-table-get-cell
+ build-table html-row last-col)
+ (gnc:html-table-set-cell!
+ build-table html-row last-col #f)
+ )
+ (set! row (+ row 1))
+ )
+ )
+ )
+
+ ;; now do the column totals
+ (let ()
+ (gnc:html-table-append-row/markup!
+ build-table "primary-subheading"
+ (append
+ (list (gnc:make-html-table-cell/markup
+ "total-label-cell" #f))
+ (gnc:html-make-empty-cells (- account-cols 1))
+ (list (tot-abs-amt-cell debit-tot))
+ (list (tot-abs-amt-cell credit-tot))
+ (if (equal? report-variant 'work-sheet)
+ (list
+ (tot-abs-amt-cell adj-debits)
+ (tot-abs-amt-cell adj-credits)
+ (tot-abs-amt-cell atb-debits)
+ (tot-abs-amt-cell atb-credits)
+ (tot-abs-amt-cell is-debits)
+ (tot-abs-amt-cell is-credits)
+ (tot-abs-amt-cell bs-debits)
+ (tot-abs-amt-cell bs-credits)
+ )
+ (list)
+ )
+ )
+ )
+ )
+ (if (equal? report-variant 'work-sheet)
+ (let* ((net-is (gnc:make-commodity-collector))
+ (net-bs (gnc:make-commodity-collector))
+ (tot-is (gnc:make-commodity-collector))
+ (tot-bs (gnc:make-commodity-collector))
+ (is-entry #f)
+ (is-credit? #f)
+ (bs-entry #f)
+ (bs-credit? #f)
+ (tbl-width (+ account-cols (* 2 bs-col) 2))
+ (this-row (gnc:html-table-num-rows build-table))
+ )
+ (net-is 'merge is-debits #f)
+ (net-is 'minusmerge is-credits #f)
+ (net-bs 'merge bs-debits #f)
+ (net-bs 'minusmerge bs-credits #f)
+ (set! is-entry
+ (gnc:double-col
+ 'entry net-is report-commodity
+ exchange-fn show-fcur?))
+ (set! is-credit?
+ (gnc:double-col
+ 'credit-q net-is report-commodity
+ exchange-fn show-fcur?))
+ (set! bs-entry
+ (gnc:double-col
+ 'entry net-bs report-commodity
+ exchange-fn show-fcur?))
+ (set! bs-credit?
+ (gnc:double-col
+ 'credit-q net-bs report-commodity
+ exchange-fn show-fcur?))
+ (gnc:html-table-add-labeled-amount-line!
+ build-table tbl-width "primary-subheading" #f
+ (if is-credit? (N_ "Net Income") (N_ "Net Loss"))
+ 0 1 "total-label-cell"
+ is-entry
+ (+ account-cols (* 2 is-col) (if is-credit? 0 1))
+ 1 "total-number-cell"
+ )
+ (gnc:html-table-set-cell!
+ build-table
+ this-row
+ (+ account-cols (* 2 bs-col) (if bs-credit? 0 1))
+ (tot-abs-amt-cell net-bs)
+ )
+ (set! this-row (+ this-row 1))
+
+ ;; now slap on the grand totals
+ (tot-is 'merge (if is-credit? is-debits is-credits) #f)
+ (if is-credit?
+ (tot-is 'minusmerge net-is #f)
+ (tot-is 'merge net-is #f))
+ (tot-bs 'merge (if bs-credit? bs-debits bs-credits) #f)
+ (if bs-credit?
+ (tot-bs 'minusmerge net-bs #f)
+ (tot-bs 'merge net-bs #f))
+
+ (gnc:html-table-append-row/markup!
+ build-table
+ "primary-subheading"
+ (append
+ (if gnc:colspans-are-working-right
+ (list (gnc:make-html-table-cell/size
+ 1 (+ account-cols (* 2 is-col)) #f))
+ (gnc:html-make-empty-cells (+ account-cols (* 2 is-col)))
+ )
+ (list
+ (tot-abs-amt-cell (if is-credit? tot-is is-debits))
+ (tot-abs-amt-cell (if is-credit? is-credits tot-is))
+ (tot-abs-amt-cell (if bs-credit? tot-bs bs-debits))
+ (tot-abs-amt-cell (if bs-credit? bs-credits tot-bs))
+ )
+ )
+ )
+ )
+ )
+
+ ;; ...and thats a complete trial balance/work sheet
+
+ (gnc:html-document-add-object! doc build-table)
+
+ ;; add currency information if requested
+ (gnc:report-percent-done 90)
+ (if show-rates?
+ (gnc:html-document-add-object!
+ doc
+ (gnc:html-make-exchangerates
+ report-commodity exchange-fn accounts)))
+ (gnc:report-percent-done 100)
+
+ ;; if sending the report to a file, do so now
+ ;; however, this still doesn't seem to get around the
+ ;; colspan bug... cf. gnc:colspans-are-working-right
+ (if filename
+ (let* ((port (open-output-file filename))
+ (gnc:display-report-list-item
+ (list doc) port " trial-balance.scm ")
+ (close-output-port port)
+ )
+ )
+ )
+ )
+ )
+
+ (gnc:report-finished)
+
+ doc
+ )
+ )
+
+(gnc:define-report
+ 'version 1.1
+ 'name reportname
+ 'menu-path (list gnc:menuname-income-expense)
+ 'options-generator trial-balance-options-generator
+ 'renderer (lambda (report-obj)
+ (trial-balance-renderer report-obj #f #f))
+ 'export-types #f
+ 'export-thunk (lambda (report-obj choice filename)
+ (trial-balance-renderer report-obj #f filename)))
+
+;; END
+
--- /dev/null
+++ src/report/standard-reports/income-statement.scm
@@ -0,0 +1,688 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; income-statement.scm: income statement (a.k.a. Profit & Loss)
+;;
+;; By David Montenegro <sunrise2000 at comcast.net>
+;; 2004.07.13 - 2004.07.14
+;;
+;; * BUGS:
+;;
+;; This code makes the assumption that you want your income
+;; statement to no more than daily resolution.
+;;
+;; The Company Name field does not currently default to the name
+;; in (gnc:get-current-book).
+;;
+;; Line & column alignments may still not conform with
+;; textbook accounting practice (they're close though!).
+;; The 'canonically-tabbed option is currently broken.
+;;
+;; Progress bar functionality is currently mostly broken.
+;;
+;; The variables in this code could use more consistent naming.
+;;
+;; See also all the "FIXME"s in the code.
+;;
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 2 of
+;; the License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, contact:
+;;
+;; Free Software Foundation Voice: +1-617-542-5942
+;; 59 Temple Place - Suite 330 Fax: +1-617-542-2652
+;; Boston, MA 02111-1307, USA gnu at gnu.org
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(define-module (gnucash report income-statement))
+(use-modules (gnucash main)) ;; FIXME: delete after we finish modularizing.
+(use-modules (ice-9 slib))
+(use-modules (gnucash gnc-module))
+
+(gnc:module-load "gnucash/report/report-system" 0)
+
+(define reportname (N_ "Income Statement"))
+
+;; define all option's names and help text so that they are properly
+;; defined in *one* place.
+(define optname-report-title (N_ "Report Title"))
+(define opthelp-report-title (N_ "Title for this report"))
+
+(define optname-party-name (N_ "Company name"))
+(define opthelp-party-name (N_ "Name of company/individual"))
+
+(define optname-start-date (N_ "Income Statement Start Date"))
+(define opthelp-start-date
+ (N_ "Start of the period this income statement will cover"))
+(define optname-end-date (N_ "Income Statement End Date"))
+(define opthelp-end-date
+ (N_ "End of the period this income statement will cover"))
+;; FIXME this could use an indent option
+
+(define optname-accounts (N_ "Accounts to include"))
+(define opthelp-accounts
+ (N_ "Report on these accounts, if display depth allows."))
+(define optname-depth-limit (N_ "Levels of Subaccounts"))
+(define opthelp-depth-limit
+ (N_ "Maximum number of levels in the account tree displayed"))
+(define optname-bottom-behavior (N_ "Flatten list to depth limit"))
+(define opthelp-bottom-behavior
+ (N_ "Displays accounts which exceed the depth limit at the depth limit"))
+
+(define optname-parent-balance-mode (N_ "Parent account balances"))
+(define opthelp-parent-balance-mode
+ (N_ "How to show any balance in parent accounts"))
+(define optname-parent-total-mode (N_ "Parent account subtotals"))
+(define opthelp-parent-total-mode
+ (N_ "How to show account subtotals for selected accounts having children"))
+
+(define optname-show-zb-accts (N_ "Include accounts with zero total balances"))
+(define opthelp-show-zb-accts
+ (N_ "Include accounts with zero total (recursive) balances in this report"))
+(define optname-omit-zb-bals (N_ "Omit zero balance figures"))
+(define opthelp-omit-zb-bals
+ (N_ "Show blank space in place of any zero balances which would be shown"))
+
+(define optname-use-rules (N_ "Show accounting-style rules"))
+(define opthelp-use-rules
+ (N_ "Use rules beneath columns of added numbers like accountants do"))
+
+(define optname-account-links (N_ "Display accounts as hyperlinks"))
+(define opthelp-account-links (N_ "Shows each account in the table as a hyperlink to its register window"))
+
+(define optname-label-revenue (N_ "Label the revenue section"))
+(define opthelp-label-revenue
+ (N_ "Whether or not to include a label for the revenue section"))
+(define optname-total-revenue (N_ "Include revenue total"))
+(define opthelp-total-revenue
+ (N_ "Whether or not to include a line indicating total revenue"))
+(define optname-label-expense (N_ "Label the expense section"))
+(define opthelp-label-expense
+ (N_ "Whether or not to include a label for the expense section"))
+(define optname-total-expense (N_ "Include expense total"))
+(define opthelp-total-expense
+ (N_ "Whether or not to include a line indicating total expense"))
+
+(define pagename-commodities (N_ "Commodities"))
+(define optname-report-commodity (N_ "Report's currency"))
+(define optname-price-source (N_ "Price Source"))
+(define optname-show-foreign (N_ "Show Foreign Currencies"))
+(define opthelp-show-foreign
+ (N_ "Display any foreign currency amount in an account"))
+(define optname-show-rates (N_ "Show Exchange Rates"))
+(define opthelp-show-rates (N_ "Show the exchange rates used"))
+
+(define pagename-entries (N_ "Entries"))
+(define optname-closing-pattern (N_ "Closing Entries pattern"))
+(define opthelp-closing-pattern
+ (N_ "Any text in the Description column which identifies closing entries"))
+(define optname-closing-casing
+ (N_ "Closing Entries pattern is case-sensitive"))
+(define opthelp-closing-casing
+ (N_ "Causes the Closing Entries Pattern match to be case-sensitive"))
+(define optname-closing-regexp
+ (N_ "Closing Entries Pattern is regular expression"))
+(define opthelp-closing-regexp
+ (N_ "Causes the Closing Entries Pattern to be treated as a regular expression"))
+
+;; This calculates the increase in the balance(s) of all accounts in
+;; <accountlist> over the period from <from-date> to <to-date>.
+;; Returns a commodity collector.
+;;
+;; Note: There is both a gnc:account-get-comm-balance-interval and
+;; gnc:group-get-comm-balance-interval which could replace this
+;; function....
+;;
+(define (accountlist-get-comm-balance-at-date accountlist from-date to-date)
+;; (for-each (lambda (x) (display x))
+;; (list "computing from: " (gnc:print-date from-date) " to "
+;; (gnc:print-date to-date) "\n"))
+ (let ((collector (gnc:make-commodity-collector)))
+ (for-each (lambda (account)
+ (let* (
+ (start-balance
+ (gnc:account-get-comm-balance-at-date
+ account from-date #f))
+ (sb (cadr (start-balance
+ 'getpair
+ (gnc:account-get-commodity account)
+ #f)))
+ (end-balance
+ (gnc:account-get-comm-balance-at-date
+ account to-date #f))
+ (eb (cadr (end-balance
+ 'getpair
+ (gnc:account-get-commodity account)
+ #f)))
+ )
+;; (for-each (lambda (x) (display x))
+;; (list "Start balance: " sb " : "
+;; (gnc:account-get-name account) " : end balance: "
+;; eb "\n"))
+ (collector 'merge end-balance #f)
+ (collector 'minusmerge start-balance #f)
+ ))
+ accountlist)
+ collector))
+
+;; options generator
+(define (income-statement-options-generator)
+ (let* ((options (gnc:new-options))
+ (add-option
+ (lambda (new-option)
+ (gnc:register-option options new-option))))
+
+ (add-option
+ (gnc:make-string-option
+ gnc:pagename-general optname-report-title
+ "a" opthelp-report-title reportname))
+ (add-option
+ (gnc:make-string-option
+ gnc:pagename-general optname-party-name
+ "b" opthelp-party-name (N_ "")))
+ ;; this should default to company name in (gnc:get-current-book)
+ ;; does anyone know the function to get the company name??
+ ;; (GnuCash is *so* well documented... sigh)
+
+ ;; period over which to report income
+ (gnc:options-add-date-interval!
+ options gnc:pagename-general
+ optname-start-date optname-end-date "c")
+
+ ;; accounts to work on
+ (add-option
+ (gnc:make-account-list-option
+ gnc:pagename-accounts optname-accounts
+ "a"
+ opthelp-accounts
+ (lambda ()
+ (gnc:filter-accountlist-type
+ ;; select, by default, only income and expense accounts
+ '(income expense)
+ (gnc:group-get-subaccounts (gnc:get-current-group))))
+ #f #t))
+ (gnc:options-add-account-levels!
+ options gnc:pagename-accounts optname-depth-limit
+ "b" opthelp-depth-limit 3)
+ (add-option
+ (gnc:make-simple-boolean-option
+ gnc:pagename-accounts optname-bottom-behavior
+ "c" opthelp-bottom-behavior #f))
+
+ ;; all about currencies
+ (gnc:options-add-currency!
+ options pagename-commodities
+ optname-report-commodity "a")
+
+ (gnc:options-add-price-source!
+ options pagename-commodities
+ optname-price-source "b" 'weighted-average)
+
+ (add-option
+ (gnc:make-simple-boolean-option
+ pagename-commodities optname-show-foreign
+ "c" opthelp-show-foreign #t))
+
+ (add-option
+ (gnc:make-simple-boolean-option
+ pagename-commodities optname-show-rates
+ "d" opthelp-show-rates #f))
+
+ ;; what to show for zero-balance accounts
+ (add-option
+ (gnc:make-simple-boolean-option
+ gnc:pagename-display optname-show-zb-accts
+ "a" opthelp-show-zb-accts #t))
+ (add-option
+ (gnc:make-simple-boolean-option
+ gnc:pagename-display optname-omit-zb-bals
+ "b" opthelp-omit-zb-bals #f))
+ ;; what to show for non-leaf accounts
+ (add-option
+ (gnc:make-multichoice-option
+ gnc:pagename-display optname-parent-balance-mode
+ "c" opthelp-parent-balance-mode
+ 'immediate-bal
+ (list (vector 'immediate-bal
+ (N_ "Show Immediate Balance")
+ (N_ "Show only the balance in the parent account, excluding any subaccounts"))
+ (vector 'recursive-bal
+ (N_ "Recursive Balance")
+ (N_ "Include subaccounts in balance"))
+ (vector 'omit-bal
+ (N_ "Omit Balance")
+ (N_ "Do not show parent account balances")))))
+ (add-option
+ (gnc:make-multichoice-option
+ gnc:pagename-display optname-parent-total-mode
+ "d" opthelp-parent-total-mode
+ 'f
+ (list (vector 't
+ (N_ "Show subtotals")
+ (N_ "Show subtotals for selected accounts which have subaccounts"))
+ (vector 'f
+ (N_ "Do not show subtotals")
+ (N_ "Do not subtotal selected parent accounts"))
+ (vector 'canonically-tabbed
+ ;;(N_ "Subtotals indented text book style")
+ (N_ "Text book style (experimental)")
+ (N_ "Show parent account subtotals, indented per text book practice (experimental)")))))
+
+ ;; some detailed formatting options
+ (add-option
+ (gnc:make-simple-boolean-option
+ gnc:pagename-display optname-account-links
+ "e" opthelp-account-links #t))
+ (add-option
+ (gnc:make-simple-boolean-option
+ gnc:pagename-display optname-use-rules
+ "f" opthelp-use-rules #f))
+
+ (add-option
+ (gnc:make-simple-boolean-option
+ gnc:pagename-display optname-label-revenue
+ "g" opthelp-label-revenue #t))
+ (add-option
+ (gnc:make-simple-boolean-option
+ gnc:pagename-display optname-total-revenue
+ "h" opthelp-total-revenue #t))
+
+ (add-option
+ (gnc:make-simple-boolean-option
+ gnc:pagename-display optname-label-expense
+ "i" opthelp-label-expense #t))
+ (add-option
+ (gnc:make-simple-boolean-option
+ gnc:pagename-display optname-total-expense
+ "j" opthelp-total-expense #t))
+
+ ;; closing entry match criteria
+ ;;
+ ;; N.B.: transactions really should have a field where we can put
+ ;; transaction types like "Adjusting/Closing/Correcting Entries"
+ (add-option
+ (gnc:make-string-option
+ pagename-entries optname-closing-pattern
+ "a" opthelp-closing-pattern (N_ "Closing Entries")))
+ (add-option
+ (gnc:make-simple-boolean-option
+ pagename-entries optname-closing-casing
+ "b" opthelp-closing-casing #f))
+ (add-option
+ (gnc:make-simple-boolean-option
+ pagename-entries optname-closing-regexp
+ "c" opthelp-closing-regexp #f))
+
+ ;; Set the accounts page as default option tab
+ (gnc:options-set-default-section options gnc:pagename-accounts)
+
+ options))
+
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; income-statement-renderer
+;; set up the document and add the table
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(define (income-statement-renderer report-obj)
+ (define (get-option pagename optname)
+ (gnc:option-value
+ (gnc:lookup-option
+ (gnc:report-options report-obj) pagename optname)))
+
+ (gnc:report-starting reportname)
+
+ ;; get all option's values
+ (let* (
+ (report-title (get-option gnc:pagename-general optname-report-title))
+ (company-name (get-option gnc:pagename-general optname-party-name))
+ (start-date-printable (gnc:date-option-absolute-time
+ (get-option gnc:pagename-general
+ optname-start-date)))
+ (start-date-tp (gnc:timepair-start-day-time
+ (gnc:date-option-absolute-time
+ (get-option gnc:pagename-general
+ optname-start-date))))
+ (end-date-tp (gnc:timepair-end-day-time
+ (gnc:date-option-absolute-time
+ (get-option gnc:pagename-general
+ optname-end-date))))
+ (accounts (get-option gnc:pagename-accounts
+ optname-accounts))
+ (depth-limit (get-option gnc:pagename-accounts
+ optname-depth-limit))
+ (bottom-behavior (get-option gnc:pagename-accounts
+ optname-bottom-behavior))
+ (report-commodity (get-option pagename-commodities
+ optname-report-commodity))
+ (price-source (get-option pagename-commodities
+ optname-price-source))
+ (show-fcur? (get-option pagename-commodities
+ optname-show-foreign))
+ (show-rates? (get-option pagename-commodities
+ optname-show-rates))
+ (parent-balance-mode (get-option gnc:pagename-display
+ optname-parent-balance-mode))
+ (parent-total-mode
+ (car
+ (assoc-ref '((t #t) (f #f) (canonically-tabbed canonically-tabbed))
+ (get-option gnc:pagename-display
+ optname-parent-total-mode))))
+ (show-zb-accts? (get-option gnc:pagename-display
+ optname-show-zb-accts))
+ (omit-zb-bals? (get-option gnc:pagename-display
+ optname-omit-zb-bals))
+ (label-revenue? (get-option gnc:pagename-display
+ optname-label-revenue))
+ (total-revenue? (get-option gnc:pagename-display
+ optname-total-revenue))
+ (label-expense? (get-option gnc:pagename-display
+ optname-label-expense))
+ (total-expense? (get-option gnc:pagename-display
+ optname-total-expense))
+ (use-links? (get-option gnc:pagename-display
+ optname-account-links))
+ (use-rules? (get-option gnc:pagename-display
+ optname-use-rules))
+ (closing-str (get-option pagename-entries
+ optname-closing-pattern))
+ (closing-cased (get-option pagename-entries
+ optname-closing-casing))
+ (closing-regexp (get-option pagename-entries
+ optname-closing-regexp))
+ (closing-pattern
+ (list (list 'str closing-str)
+ (list 'cased closing-cased)
+ (list 'regexp closing-regexp)
+ )
+ )
+ (indent 0)
+ (tabbing #f)
+
+ ;; decompose the account list
+ (split-up-accounts (gnc:decompose-accountlist accounts))
+ (revenue-accounts (assoc-ref split-up-accounts 'income))
+ (expense-accounts (assoc-ref split-up-accounts 'expense))
+ (income-expense-accounts
+ (append (assoc-ref split-up-accounts 'income)
+ (assoc-ref split-up-accounts 'expense)))
+
+ (doc (gnc:make-html-document))
+ ;; this can occasionally put extra (blank) columns in our
+ ;; table (when there is one account at the maximum depth and
+ ;; it has at least one of its ancestors deselected), but this
+ ;; is the only simple way to ensure that both tables
+ ;; (revenue, expense) have the same width.
+ (tree-depth (if (equal? depth-limit 'all)
+ (gnc:get-current-group-depth)
+ depth-limit))
+ ;; exchange rates calculation parameters
+ (exchange-fn
+ (gnc:case-exchange-fn price-source report-commodity end-date-tp))
+ )
+
+ ;; Wrapper to call gnc:html-table-add-labeled-amount-line!
+ ;; with the proper arguments.
+ (define (add-subtotal-line table pos-label neg-label signed-balance)
+ (define allow-same-column-totals #t)
+ (let* ((neg? (and signed-balance
+ neg-label
+ (gnc:numeric-negative-p
+ (gnc:gnc-monetary-amount
+ (gnc:sum-collector-commodity
+ signed-balance report-commodity exchange-fn)))))
+ (label (if neg? (or neg-label pos-label) pos-label))
+ (balance (if neg?
+ (let ((bal (gnc:make-commodity-collector)))
+ (bal 'minusmerge signed-balance #f)
+ bal)
+ signed-balance))
+ )
+ (gnc:html-table-add-labeled-amount-line!
+ table
+ (+ indent (* tree-depth 2)
+ (if (equal? tabbing 'canonically-tabbed) 1 0))
+ "primary-subheading"
+ (and (not allow-same-column-totals) balance use-rules?)
+ label indent 1 "total-label-cell"
+ (gnc:sum-collector-commodity balance report-commodity exchange-fn)
+ (+ indent (* tree-depth 2) (- 0 1)
+ (if (equal? tabbing 'canonically-tabbed) 1 0))
+ 1 "total-number-cell")
+ )
+ )
+
+ ;; wrapper around gnc:html-table-append-ruler!
+ (define (add-rule table)
+ (gnc:html-table-append-ruler!
+ table
+ (+ (* 2 tree-depth)
+ (if (equal? tabbing 'canonically-tabbed) 1 0))))
+
+ (gnc:html-document-set-title!
+ doc (sprintf #f
+ (string-append "%s %s "
+ (N_ "For Period Covering")
+ " %s "
+ (N_ "to")
+ " %s")
+ company-name report-title
+ (gnc:print-date start-date-printable)
+ (gnc:print-date end-date-tp)))
+
+ (if (null? accounts)
+
+ ;; error condition: no accounts specified
+ ;; is this *really* necessary??
+ ;; i'd be fine with an all-zero P&L
+ ;; that would, technically, be correct....
+ (gnc:html-document-add-object!
+ doc
+ (gnc:html-make-no-account-warning
+ reportname (gnc:report-id report-obj)))
+
+ ;; Get all the balances for each account group.
+ (let* ((revenue-closing #f)
+ (expense-closing #f)
+ (neg-revenue-total #f)
+ (revenue-total #f)
+ (expense-total #f)
+ (net-income #f)
+
+ ;; Create the account tables below where their
+ ;; percentage time can be tracked.
+ (build-table (gnc:make-html-table)) ;; gnc:html-table
+ (table-env #f) ;; parameters for :make-
+ (params #f) ;; and -add-account-
+ (revenue-table #f) ;; gnc:html-acct-table
+ (expense-table #f) ;; gnc:html-acct-table
+
+ (terse-period? #t)
+ (period-for (if terse-period?
+ (string-append " " (N_ "for Period"))
+ (string-append
+ ", "
+ (gnc:print-date start-date-printable) " "
+ (N_ "to") " "
+ (gnc:print-date end-date-tp)
+ )
+ )
+ )
+ )
+
+ ;; a helper to add a line to our report
+ (define (report-line
+ table pos-label neg-label amount col
+ exchange-fn rule? row-style)
+ (let* ((neg? (and amount
+ neg-label
+ (gnc:numeric-negative-p
+ (gnc:gnc-monetary-amount
+ (gnc:sum-collector-commodity
+ amount report-commodity exchange-fn)))))
+ (label (if neg? (or neg-label pos-label) pos-label))
+ (pos-bal (if neg?
+ (let ((bal (gnc:make-commodity-collector)))
+ (bal 'minusmerge amount #f)
+ bal)
+ amount))
+ (bal (gnc:sum-collector-commodity
+ pos-bal report-commodity exchange-fn))
+ (balance
+ (or (and (gnc:uniform-commodity? pos-bal report-commodity)
+ bal)
+ (and show-fucr?
+ (gnc:commodity-table
+ pos-bal report-commodity exchange-fn))
+ bal
+ ))
+ (column (or col 0))
+ )
+ (gnc:html-table-add-labeled-amount-line!
+ table (* 2 tree-depth) row-style rule?
+ label 0 1 "text-cell"
+ bal (+ col 1) 1 "number-cell")
+ )
+ )
+
+ ;; sum revenues and expenses
+ (set! revenue-closing
+ (gnc:account-get-trans-type-balance-interval
+ revenue-accounts closing-pattern
+ start-date-tp end-date-tp)
+ ) ;; this is norm positive (debit)
+ (set! expense-closing
+ (gnc:account-get-trans-type-balance-interval
+ expense-accounts closing-pattern
+ start-date-tp end-date-tp)
+ ) ;; this is norm negative (credit)
+ (set! expense-total
+ (accountlist-get-comm-balance-at-date
+ expense-accounts
+ start-date-tp end-date-tp))
+ (expense-total 'minusmerge expense-closing #f)
+ (set! neg-revenue-total
+ (accountlist-get-comm-balance-at-date
+ revenue-accounts
+ start-date-tp end-date-tp))
+ (neg-revenue-total 'minusmerge revenue-closing #f)
+ (set! revenue-total (gnc:make-commodity-collector))
+ (revenue-total 'minusmerge neg-revenue-total #f)
+ ;; calculate net income
+ (set! net-income (gnc:make-commodity-collector))
+ (net-income 'merge revenue-total #f)
+ (net-income 'minusmerge expense-total #f)
+
+ (set! table-env
+ (list
+ (list 'start-date start-date-tp)
+ (list 'end-date end-date-tp)
+ (list 'display-tree-depth tree-depth)
+ (list 'depth-limit-behavior (if bottom-behavior
+ 'flatten
+ 'summarize))
+ (list 'report-commodity report-commodity)
+ (list 'exchange-fn exchange-fn)
+ (list 'parent-account-subtotal-mode parent-total-mode)
+ (list 'zero-balance-mode (if show-zb-accts?
+ 'show-leaf-acct
+ 'omit-leaf-acct))
+ (list 'account-label-mode (if use-links?
+ 'anchor
+ 'name))
+ ;; we may, at some point, want to add an option to
+ ;; generate a pre-adjustment income statement...
+ (list 'balance-mode 'pre-closing)
+ (list 'closing-pattern closing-pattern)
+ )
+ )
+ (set! params
+ (list
+ (list 'parent-account-balance-mode parent-balance-mode)
+ (list 'zero-balance-display-mode (if omit-zb-bals?
+ 'omit-balance
+ 'show-balance))
+ (list 'multicommodity-mode (if show-fcur? 'table #f))
+ (list 'rule-mode use-rules?)
+ )
+ )
+
+ ;; Workaround to force gtkhtml into displaying wide
+ ;; enough columns.
+ (let ((space
+ (make-list tree-depth " \
+ \
+ ")
+ ))
+ (gnc:html-table-append-row! build-table space)
+ )
+
+ (gnc:report-percent-done 80)
+ (if label-revenue?
+ (add-subtotal-line build-table (_ "Revenues") #f #f))
+ (set! revenue-table
+ (gnc:make-html-acct-table/env/accts
+ table-env revenue-accounts))
+ (gnc:html-table-add-account-balances
+ build-table revenue-table params)
+ (if total-revenue?
+ (add-subtotal-line
+ build-table (_ "Total Revenue") #f revenue-total))
+
+ (gnc:report-percent-done 85)
+ (if label-expense?
+ (add-subtotal-line
+ build-table (_ "Expenses") #f #f))
+ (set! expense-table
+ (gnc:make-html-acct-table/env/accts
+ table-env expense-accounts))
+ (gnc:html-table-add-account-balances
+ build-table expense-table params)
+ (if total-expense?
+ (add-subtotal-line
+ build-table (_ "Total Expenses") #f expense-total))
+
+ (report-line
+ build-table
+ (string-append (N_ "Net income") period-for)
+ (string-append (N_ "Net loss") period-for)
+ net-income
+ (* 2 (- tree-depth 1)) exchange-fn #f #f
+ )
+
+ (gnc:html-document-add-object! doc build-table)
+
+ ;; add currency information if requested
+ (gnc:report-percent-done 90)
+ (if show-rates?
+ (gnc:html-document-add-object!
+ doc ;;(gnc:html-markup-p)
+ (gnc:html-make-exchangerates
+ report-commodity exchange-fn accounts)))
+ (gnc:report-percent-done 100)
+
+ )
+ )
+
+ (gnc:report-finished)
+
+ doc
+ )
+ )
+
+(gnc:define-report
+ 'version 2 ;; but it doesn't matter... :)
+ 'name reportname
+ 'menu-path (list gnc:menuname-income-expense)
+ 'options-generator income-statement-options-generator
+ 'renderer income-statement-renderer
+ )
+
+;; END
+
Index: equity-statement.scm
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/report/standard-reports/equity-statement.scm,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -Lsrc/report/standard-reports/equity-statement.scm -Lsrc/report/standard-reports/equity-statement.scm -u -r1.1.2.1 -r1.1.2.2
--- src/report/standard-reports/equity-statement.scm
+++ src/report/standard-reports/equity-statement.scm
@@ -19,7 +19,8 @@
;; statement to no more than daily resolution.
;;
;; The Accounts option panel needs a way to select (and select by
-;; default) capital and draw accounts.
+;; default) capital and draw accounts. There really should be a
+;; contra account type or attribute....
;;
;; The variables in this code could use more consistent naming.
;;
@@ -87,6 +88,19 @@
(define optname-show-rates (N_ "Show Exchange Rates"))
(define opthelp-show-rates (N_ "Show the exchange rates used"))
+(define pagename-entries (N_ "Entries"))
+(define optname-closing-pattern (N_ "Closing Entries pattern"))
+(define opthelp-closing-pattern
+ (N_ "Any text in the Description column which identifies closing entries"))
+(define optname-closing-casing
+ (N_ "Closing Entries pattern is case-sensitive"))
+(define opthelp-closing-casing
+ (N_ "Causes the Closing Entries Pattern match to be case-sensitive"))
+(define optname-closing-regexp
+ (N_ "Closing Entries Pattern is regular expression"))
+(define opthelp-closing-regexp
+ (N_ "Causes the Closing Entries Pattern to be treated as a regular expression"))
+
;; This calculates the increase in the balance(s) of all accounts in
;; <accountlist> over the period from <start-date> to <end-date>.
;; Returns a commodity collector.
@@ -189,6 +203,23 @@
gnc:pagename-display optname-use-rules
"f" opthelp-use-rules #f))
+ ;; closing entry match criteria
+ ;;
+ ;; N.B.: transactions really should have a field where we can put
+ ;; transaction types like "Adjusting/Closing/Correcting Entries"
+ (add-option
+ (gnc:make-string-option
+ pagename-entries optname-closing-pattern
+ "a" opthelp-closing-pattern (N_ "Closing Entries")))
+ (add-option
+ (gnc:make-simple-boolean-option
+ pagename-entries optname-closing-casing
+ "b" opthelp-closing-casing #f))
+ (add-option
+ (gnc:make-simple-boolean-option
+ pagename-entries optname-closing-regexp
+ "c" opthelp-closing-regexp #f))
+
;; Set the accounts page as default option tab
(gnc:options-set-default-section options gnc:pagename-accounts)
@@ -241,6 +272,12 @@
optname-show-rates))
(use-rules? (get-option gnc:pagename-display
optname-use-rules))
+ (closing-str (get-option pagename-entries
+ optname-closing-pattern))
+ (closing-cased (get-option pagename-entries
+ optname-closing-casing))
+ (closing-regexp (get-option pagename-entries
+ optname-closing-regexp))
;; decompose the account list
(split-up-accounts (gnc:decompose-accountlist accounts))
@@ -257,6 +294,17 @@
;; these must still be split-out and itemized separately
(capital-accounts #f)
(drawing-accounts #f)
+ (investments #f)
+ (withdrawals #f)
+ (net-investment #f)
+ (income-expense-closing #f)
+ (closing-pattern
+ (list (list 'str closing-str)
+ (list 'cased closing-cased)
+ (list 'regexp closing-regexp)
+ (list 'positive #f)
+ )
+ )
(doc (gnc:make-html-document))
;; exchange rates calculation parameters
@@ -271,11 +319,11 @@
(gnc:html-document-set-title!
doc (sprintf #f
(string-append "%s %s "
- (N_ "For Period")
+ (N_ "For Period Covering")
" %s "
(N_ "to")
" %s")
- report-title company-name
+ company-name report-title
(gnc:print-date start-date-printable)
(gnc:print-date end-date-tp)))
@@ -303,6 +351,8 @@
(neg-start-equity-balance #f)
(neg-end-equity-balance #f)
+ ;; these variables wont be used until gnucash gets
+ ;; conta account types
(start-capital-balance #f)
(end-capital-balance #f)
(start-drawing-balance #f)
@@ -315,14 +365,14 @@
(end-unrealized-gains #f)
(net-unrealized-gains #f)
- (start-total-equity #f)
- (end-total-equity #f)
-
- (investments #f)
- (draws #f)
+ (equity-closing #f)
+ (neg-pre-closing-equity #f)
(capital-increase #f)
+ (start-total-equity #f)
+ (end-total-equity #f)
+
;; Create the account table below where its
;; percentage time can be tracked.
(build-table (gnc:make-html-table)) ;; gnc:html-table
@@ -350,6 +400,7 @@
table pos-label neg-label amount col
exchange-fn rule? row-style)
(let* ((neg? (and amount
+ neg-label
(gnc:numeric-negative-p
(gnc:gnc-monetary-amount
(gnc:sum-collector-commodity
@@ -363,10 +414,11 @@
(bal (gnc:sum-collector-commodity
pos-bal report-commodity exchange-fn))
(balance
- (or (and (gnc:uniform-commodity? bal report-commodity) bal)
+ (or (and (gnc:uniform-commodity? pos-bal report-commodity)
+ bal)
(and show-fucr?
(gnc:commodity-table
- bal report-commodity exchange-fn))
+ pos-bal report-commodity exchange-fn))
bal
))
(column (or col 0))
@@ -444,12 +496,26 @@
(accountlist-get-comm-balance-at-date
income-expense-accounts
forever-ago end-date-tp)) ; OK
+ ;; neg-pre-end-retained-earnings is not used to calculate
+ ;; profit but is used to calculate unrealized gains
+
+ ;; calculate net income
+ ;; first, ask out how much profit/loss was closed
+ (set! income-expense-closing
+ (gnc:account-get-trans-type-balance-interval
+ income-expense-accounts closing-pattern
+ start-date-tp end-date-tp)
+ )
+ ;; find retained earnings for the period
(set! neg-net-income
(accountlist-get-comm-balance-at-date
income-expense-accounts
start-date-tp end-date-tp)) ; OK
+ ;; revert the income/expense to its pre-closing balance
+ (neg-net-income 'minusmerge income-expense-closing #f)
(set! net-income (gnc:make-commodity-collector))
(net-income 'minusmerge neg-net-income #f)
+ ;; now we know the net income for the period
;; start and end (unadjusted) equity balances
(set! neg-start-equity-balance
@@ -458,6 +524,8 @@
(set! neg-end-equity-balance
(gnc:accounts-get-comm-total-assets
equity-accounts get-end-balance-fn)) ; OK
+ ;; neg-end-equity-balance is used to calculate unrealized
+ ;; gains and investments/withdrawals
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
@@ -482,6 +550,10 @@
(unrealized-gains-at-date start-book-balance
start-exchange-fn
start-date-tp)) ; OK
+ ;; I suspect that unrealized gains (since never realized)
+ ;; must be counted from forever-ago....
+ ;; ...yep, this appears to be correct.
+ (set! start-unrealized-gains (gnc:make-commodity-collector))
(set! end-unrealized-gains
(unrealized-gains-at-date end-book-balance
end-exchange-fn
@@ -492,17 +564,6 @@
(net-unrealized-gains 'merge end-unrealized-gains #f)
(net-unrealized-gains 'minusmerge start-unrealized-gains #f) ; OK
- ;; starting and ending total equity...
- (set! start-total-equity (gnc:make-commodity-collector))
- (start-total-equity 'minusmerge neg-start-equity-balance #f)
- (start-total-equity 'minusmerge neg-pre-start-retained-earnings #f)
- (start-total-equity 'merge start-unrealized-gains #f) ; OK
-
- (set! end-total-equity (gnc:make-commodity-collector))
- (end-total-equity 'minusmerge neg-end-equity-balance #f)
- (end-total-equity 'minusmerge neg-pre-end-retained-earnings #f)
- (end-total-equity 'merge end-unrealized-gains #f) ; OK
-
;;
;; calculate investments & draws...
;;
@@ -511,21 +572,52 @@
;; bit... i'll do a transaction query and classify the
;; splits by debit/credit.
;;
+ ;; withdrawals = investments - (investments - withdrawals)
+ ;; investments = withdrawals + (investments - withdrawals)
+ ;;
+ ;; assume that positive shares on an equity account are debits...
+ ;;
- ;; FIXME: um... no. that sounds like too much work.
- ;; ok, for now, just assume draws are zero and investments signed
- (set! draws (gnc:make-commodity-collector)) ;; 0
- (set! investments (gnc:make-commodity-collector)) ;; 0
- (investments 'minusmerge neg-end-equity-balance #f) ;; > 0
- (investments 'merge neg-start-equity-balance #f) ;; net increase
+ (set! equity-closing
+ (gnc:account-get-trans-type-balance-interval
+ equity-accounts closing-pattern
+ start-date-tp end-date-tp)
+ )
+ (set! neg-pre-closing-equity (gnc:make-commodity-collector))
+ (neg-pre-closing-equity 'merge neg-end-equity-balance #f)
+ (neg-pre-closing-equity 'minusmerge equity-closing #f)
+
+ (set! net-investment (gnc:make-commodity-collector)) ;; 0
+ (net-investment 'minusmerge neg-pre-closing-equity #f);; > 0
+ (net-investment 'merge neg-start-equity-balance #f) ;; net increase
+
+ (set! withdrawals (gnc:make-commodity-collector))
+ (withdrawals 'merge (gnc:account-get-pos-trans-total-interval
+ equity-accounts closing-pattern
+ start-date-tp end-date-tp)
+ #f)
+ (set! investments (gnc:make-commodity-collector))
+ (investments 'merge net-investment #f)
+ (investments 'merge withdrawals #f)
;; increase in equity
(set! capital-increase (gnc:make-commodity-collector))
(capital-increase 'merge net-income #f)
(capital-increase 'merge investments #f)
- (capital-increase 'minusmerge draws #f)
+ (capital-increase 'minusmerge withdrawals #f)
(capital-increase 'merge net-unrealized-gains #f)
+ ;; starting total equity
+ (set! start-total-equity (gnc:make-commodity-collector))
+ (start-total-equity 'minusmerge neg-start-equity-balance #f)
+ (start-total-equity 'minusmerge neg-pre-start-retained-earnings #f)
+ (start-total-equity 'merge start-unrealized-gains #f) ; OK
+
+ ;; ending total equity
+ (set! end-total-equity (gnc:make-commodity-collector))
+ (end-total-equity 'merge start-total-equity #f)
+ (end-total-equity 'merge capital-increase #f) ; OK
+
(gnc:report-percent-done 30)
;; Workaround to force gtkhtml into displaying wide
@@ -555,18 +647,27 @@
)
(report-line
build-table
- (string-append (N_ "Investments less withdrawals") period-for)
+ (string-append (N_ "Investments") period-for)
#f
investments
0 end-exchange-fn #f #f
)
(report-line
build-table
- (string-append (N_ "Unrealized gains") period-for)
- (string-append (N_ "Unrealized losses") period-for)
- net-unrealized-gains
+ (string-append (N_ "Withdrawals") period-for)
+ #f
+ withdrawals
0 end-exchange-fn #f #f
)
+ (or (gnc:commodity-collector-allzero? net-unrealized-gains)
+ (report-line
+ build-table
+ (N_ "Unrealized gains")
+ (N_ "Unrealized losses")
+ net-unrealized-gains
+ 0 end-exchange-fn #f #f
+ )
+ )
(report-line
build-table
(N_ "Increase in capital")
--- src/report/standard-reports/pnl.scm
+++ /dev/null
@@ -1,241 +0,0 @@
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; pnl.scm : profit-and-loss report
-;;
-;; By Christian Stimming <stimming at tu-harburg.de>
-;;
-;; This program is free software; you can redistribute it and/or
-;; modify it under the terms of the GNU General Public License as
-;; published by the Free Software Foundation; either version 2 of
-;; the License, or (at your option) any later version.
-;;
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program; if not, contact:
-;;
-;; Free Software Foundation Voice: +1-617-542-5942
-;; 59 Temple Place - Suite 330 Fax: +1-617-542-2652
-;; Boston, MA 02111-1307, USA gnu at gnu.org
-;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(define-module (gnucash report pnl))
-
-(use-modules (gnucash main)) ;; FIXME: delete after we finish modularizing.
-(use-modules (srfi srfi-1))
-(use-modules (ice-9 slib))
-(use-modules (gnucash gnc-module))
-
-(require 'printf)
-
-(gnc:module-load "gnucash/report/report-system" 0)
-
-;; Profit and loss report. Actually, people in finances might want
-;; something different under this name, but they are welcomed to
-;; contribute their changes :-)
-
-(define reportname (N_ "Profit And Loss"))
-
-;; define all option's names so that they are properly defined
-;; in *one* place.
-(define optname-from-date (N_ "From"))
-(define optname-to-date (N_ "To"))
-
-(define optname-display-depth (N_ "Account Display Depth"))
-(define optname-show-subaccounts (N_ "Always show sub-accounts"))
-(define optname-accounts (N_ "Account"))
-
-(define optname-group-accounts (N_ "Group the accounts"))
-(define optname-show-parent-balance (N_ "Show balances for parent accounts"))
-(define optname-show-parent-total (N_ "Show subtotals"))
-
-(define optname-show-foreign (N_ "Show Foreign Currencies"))
-(define optname-report-currency (N_ "Report's currency"))
-(define optname-price-source (N_ "Price Source"))
-(define optname-show-rates (N_ "Show Exchange Rates"))
-(define optname-show-zeros (N_ "Show accounts with a 0.0 total"))
-
-;; options generator
-(define (pnl-options-generator)
- (let ((options (gnc:new-options)))
-
- ;; date at which to report balance
- (gnc:options-add-date-interval!
- options gnc:pagename-general
- optname-from-date optname-to-date "a")
-
- ;; all about currencies
- (gnc:options-add-currency!
- options gnc:pagename-general
- optname-report-currency "b")
-
- (gnc:options-add-price-source!
- options gnc:pagename-general
- optname-price-source "c" 'weighted-average)
-
- ;; accounts to work on
- (gnc:options-add-account-selection!
- options gnc:pagename-accounts
- optname-display-depth optname-show-subaccounts
- optname-accounts "a" 2
- (lambda ()
- (filter
- gnc:account-is-inc-exp?
- (gnc:group-get-account-list (gnc:get-current-group))))
- #t)
-
- ;; with or without grouping
- (gnc:options-add-group-accounts!
- options gnc:pagename-display optname-group-accounts "b" #t)
-
- ;; what to show about non-leaf accounts
- (gnc:register-option
- options
- (gnc:make-simple-boolean-option
- gnc:pagename-display optname-show-parent-balance
- "c" (N_ "Show balances for parent accounts") #f))
-
- ;; have a subtotal for each parent account?
- (gnc:register-option
- options
- (gnc:make-simple-boolean-option
- gnc:pagename-display optname-show-parent-total
- "d" (N_ "Show subtotals for parent accounts") #t))
-
- (gnc:register-option
- options
- (gnc:make-simple-boolean-option
- gnc:pagename-display optname-show-foreign
- "e" (N_ "Display the account's foreign currency amount?") #f))
-
- (gnc:register-option
- options
- (gnc:make-simple-boolean-option
- gnc:pagename-display optname-show-rates
- "f" (N_ "Show the exchange rates used") #t))
-
- (gnc:register-option
- options
- (gnc:make-simple-boolean-option
- gnc:pagename-display optname-show-zeros
- "g" (N_ "Show account with 0.0 balance") #t))
-
- ;; Set the general page as default option tab
- (gnc:options-set-default-section options gnc:pagename-general)
-
- options))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; pnl-renderer
-;; set up the document and add the table
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(define (pnl-renderer report-obj)
- (define (get-option pagename optname)
- (gnc:option-value
- (gnc:lookup-option
- (gnc:report-options report-obj) pagename optname)))
-
- (gnc:report-starting reportname)
-
- ;; get all option's values
- (let* ((display-depth (get-option gnc:pagename-accounts
- optname-display-depth))
- (show-subaccts? (get-option gnc:pagename-accounts
- optname-show-subaccounts))
- (accounts (filter gnc:account-is-inc-exp?
- (get-option gnc:pagename-accounts
- optname-accounts)))
- (do-grouping? (get-option gnc:pagename-display
- optname-group-accounts))
- (show-parent-balance? (get-option gnc:pagename-display
- optname-show-parent-balance))
- (show-parent-total? (get-option gnc:pagename-display
- optname-show-parent-total))
- (show-fcur? (get-option gnc:pagename-display
- optname-show-foreign))
- (report-currency (get-option gnc:pagename-general
- optname-report-currency))
- (price-source (get-option gnc:pagename-general
- optname-price-source))
- (show-rates? (get-option gnc:pagename-display
- optname-show-rates))
- (show-zeros? (get-option gnc:pagename-display
- optname-show-zeros))
- (to-date-tp (gnc:timepair-end-day-time
- (gnc:date-option-absolute-time
- (get-option gnc:pagename-general
- optname-to-date))))
- (from-date-tp (gnc:timepair-start-day-time
- (gnc:date-option-absolute-time
- (get-option gnc:pagename-general
- optname-from-date))))
- (report-title (sprintf #f
- (_ "%s - %s to %s")
- (get-option gnc:pagename-general gnc:optname-reportname)
- (gnc:print-date from-date-tp)
- (gnc:print-date to-date-tp)))
- (doc (gnc:make-html-document)))
-
- (gnc:html-document-set-title!
- doc report-title)
- (if (not (null? accounts))
- ;; if no max. tree depth is given we have to find the
- ;; maximum existing depth
- (let* ((tree-depth (+ (if (equal? display-depth 'all)
- (gnc:get-current-group-depth)
- display-depth)
- (if do-grouping? 1 0)))
-
- (exchange-fn #f)
- (table #f))
-
- ;; calculate the exchange rates
- (gnc:report-percent-done 1)
- (set! exchange-fn (gnc:case-exchange-fn
- price-source report-currency to-date-tp))
- (gnc:report-percent-done 10)
-
- ;; do the processing here
- (set! table (gnc:html-build-acct-table
- from-date-tp to-date-tp
- tree-depth show-subaccts? accounts 10 80 #f
- #t gnc:accounts-get-comm-total-profit
- (_ "Profit") do-grouping?
- show-parent-balance? show-parent-total?
- show-fcur? report-currency exchange-fn show-zeros?))
- ;; add the table
- (gnc:html-document-add-object! doc table)
-
- ;; add currency information
- (if show-rates?
- (gnc:html-document-add-object!
- doc ;;(gnc:html-markup-p
- (gnc:html-make-exchangerates
- report-currency exchange-fn
- (append-map
- (lambda (a)
- (gnc:group-get-subaccounts
- (gnc:account-get-children a)))
- accounts))))
- (gnc:report-percent-done 100))
-
- ;; error condition: no accounts specified
-
- (gnc:html-document-add-object!
- doc
- (gnc:html-make-no-account-warning
- report-title (gnc:report-id report-obj))))
- (gnc:report-finished)
- doc))
-
-(gnc:define-report
- 'version 1
- 'name reportname
- 'menu-name (N_ "Profit & Loss")
- 'menu-path (list gnc:menuname-income-expense)
- 'options-generator pnl-options-generator
- 'renderer pnl-renderer)
Index: standard-reports.scm
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/report/standard-reports/standard-reports.scm,v
retrieving revision 1.14.4.2
retrieving revision 1.14.4.3
diff -Lsrc/report/standard-reports/standard-reports.scm -Lsrc/report/standard-reports/standard-reports.scm -u -r1.14.4.2 -r1.14.4.3
--- src/report/standard-reports/standard-reports.scm
+++ src/report/standard-reports/standard-reports.scm
@@ -72,14 +72,17 @@
(use-modules (gnucash report average-balance))
(use-modules (gnucash report balance-sheet))
(use-modules (gnucash report equity-statement))
+(use-modules (gnucash report general-journal))
+(use-modules (gnucash report general-ledger))
(use-modules (gnucash report cash-flow))
(use-modules (gnucash report category-barchart))
(use-modules (gnucash report daily-reports))
(use-modules (gnucash report net-barchart))
-(use-modules (gnucash report pnl))
+(use-modules (gnucash report income-statement))
(use-modules (gnucash report portfolio))
(use-modules (gnucash report price-scatter))
(use-modules (gnucash report register))
+(use-modules (gnucash report trial-balance))
(use-modules (gnucash report transaction))
(use-modules (gnucash gnc-module))
--- /dev/null
+++ src/report/standard-reports/general-ledger.scm
@@ -0,0 +1,138 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; general-ledger.scm: general ledger report
+;;
+;; By David Montenegro <sunrise2000 at comcast.net> 2004.07.13
+;;
+;; * BUGS:
+;;
+;; See any "FIXME"s in the code.
+;;
+;; Largely borrowed from welcome-to-gnucash.scm by
+;; Bill Gribble <grib at gnumatic.com>
+;;
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 2 of
+;; the License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, contact:
+;;
+;; Free Software Foundation Voice: +1-617-542-5942
+;; 59 Temple Place - Suite 330 Fax: +1-617-542-2652
+;; Boston, MA 02111-1307, USA gnu at gnu.org
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(define-module (gnucash report general-ledger))
+(export gnc:make-general-ledger-report)
+(use-modules (gnucash main)) ;; FIXME: delete after we finish modularizing.
+(use-modules (ice-9 slib))
+(use-modules (gnucash gnc-module))
+
+(gnc:module-load "gnucash/report/report-system" 0)
+
+(define reportname (N_ "General Ledger"))
+(define xactrptname "Transaction Report")
+
+;; report constructor
+
+(define (gnc:make-general-ledger-report)
+ (let* ((xactrpt (gnc:make-report xactrptname)))
+ xactrpt))
+
+;; options generator
+
+(define (general-ledger-options-generator)
+
+ (let* ((options (gnc:report-template-new-options/name xactrptname))
+ )
+
+ (define pagename-sorting (N_ "Sorting"))
+ (define (set-option! section name value)
+ (gnc:option-set-value
+ (gnc:lookup-option options section name) value))
+
+ ;; set options in the accounts tab...
+ (set-option!
+ gnc:pagename-accounts (N_ "Filter Type") 'none)
+ (set-option!
+ gnc:pagename-accounts (N_ "Void Transactions?") 'non-void-only)
+
+ ;; set options in the display tab...
+ (for-each
+ (lambda (l)
+ (set-option! gnc:pagename-display (car l) (cadr l)))
+ ;; One list per option here with: option-name, default-value
+ (list
+ (list (N_ "Date") #t)
+ (list (N_ "Reconciled Date") #f)
+ (list (N_ "Num") #f)
+ (list (N_ "Description") #t)
+ (list (N_ "Memo") #f)
+ (list (N_ "Account Name") #f)
+ (list (N_ "Use Full Account Name?") #f)
+ (list (N_ "Account Code") #f)
+ (list (N_ "Other Account Name") #f)
+ (list (N_ "Use Full Other Account Name?") #f)
+ (list (N_ "Other Account Code") #f)
+ (list (N_ "Shares") #f)
+ (list (N_ "Price") #f)
+ ;; note the "Amount" multichoice option here
+ (list (N_ "Amount") 'double)
+ (list (N_ "Running Balance") #t)
+ (list (N_ "Totals") #f)
+ (list (N_ "Sign Reverses?") 'credit-accounts)
+ )
+ )
+
+ ;; set options in the general tab...
+ (set-option!
+ gnc:pagename-general (N_ "Style") 'single)
+ ;; we can't (currently) set the Report name here
+ ;; because it is automatically set to the template
+ ;; name... :(
+
+ ;; set options in the sorting tab...
+ (for-each
+ (lambda (l)
+ (set-option! pagename-sorting (car l) (cadr l)))
+ ;; One list per option here with: option-name, default-value
+ (list
+ (list (N_ "Primary Key") 'account-code)
+ (list (N_ "Show Full Account Name?") #f)
+ (list (N_ "Show Account Code?") #t)
+ (list (N_ "Primary Subtotal") #t)
+ (list (N_ "Primary Subtotal for Date Key") 'none)
+ (list (N_ "Primary Sort Order") 'ascend)
+ (list (N_ "Secondary Key") 'register-order)
+ (list (N_ "Secondary Subtotal") #t)
+ (list (N_ "Secondary Subtotal for Date Key") 'none)
+ (list (N_ "Secondary Sort Order") 'ascend)
+ )
+ )
+
+ options)
+ )
+
+;; report renderer
+
+(define (general-ledger-renderer report-obj)
+ ;; just delegate rendering to the Transaction Report renderer...
+ ((gnc:report-template-renderer/name xactrptname) report-obj))
+
+(gnc:define-report
+ 'version 1
+ 'name reportname
+ 'menu-path (list gnc:menuname-asset-liability)
+ 'options-generator general-ledger-options-generator
+ 'renderer general-ledger-renderer
+ )
+
+;; END
+
Index: Makefile.am
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/report/standard-reports/Makefile.am,v
retrieving revision 1.12.4.2
retrieving revision 1.12.4.3
diff -Lsrc/report/standard-reports/Makefile.am -Lsrc/report/standard-reports/Makefile.am -u -r1.12.4.2 -r1.12.4.3
--- src/report/standard-reports/Makefile.am
+++ src/report/standard-reports/Makefile.am
@@ -32,11 +32,14 @@
daily-reports.scm \
equity-statement.scm \
net-barchart.scm \
- pnl.scm \
+ income-statement.scm \
portfolio.scm \
price-scatter.scm \
register.scm \
standard-reports.scm \
+ trial-balance.scm \
+ general-journal.scm \
+ general-ledger.scm \
transaction.scm
EXTRA_DIST = ${gncscmmod_DATA}
--- /dev/null
+++ src/report/standard-reports/general-journal.scm
@@ -0,0 +1,129 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; general-journal.scm: general journal report
+;;
+;; By David Montenegro <sunrise2000 at comcast.net> 2004.07.14
+;;
+;; * BUGS:
+;;
+;; See any "FIXME"s in the code.
+;;
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 2 of
+;; the License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, contact:
+;;
+;; Free Software Foundation Voice: +1-617-542-5942
+;; 59 Temple Place - Suite 330 Fax: +1-617-542-2652
+;; Boston, MA 02111-1307, USA gnu at gnu.org
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(define-module (gnucash report general-journal))
+(export gnc:make-general-journal-report)
+(use-modules (gnucash main)) ;; FIXME: delete after we finish modularizing.
+(use-modules (ice-9 slib))
+(use-modules (gnucash gnc-module))
+
+(gnc:module-load "gnucash/report/report-system" 0)
+
+(define reportname (N_ "General Journal"))
+(define regrptname "Register")
+
+;; report constructor
+
+(define (gnc:make-general-journal-report)
+ (let* ((regrpt (gnc:make-report regrptname)))
+ regrpt))
+
+;; options generator
+
+(define (general-journal-options-generator)
+
+ (let* ((options (gnc:report-template-new-options/name regrptname))
+ (query (gnc:malloc-query))
+ )
+
+ (define (set-option! section name value)
+ (gnc:option-set-value
+ (gnc:lookup-option options section name) value))
+
+ ;; Match, by default, all non-void transactions ever recorded in
+ ;; all accounts.... Whether or not to match void transactions,
+ ;; however, may be of issue here. Since I don't know if the
+ ;; Register Report properly ignores voided transactions, I'll err
+ ;; on the side of safety by excluding them from the query....
+ (gnc:query-set-book query (gnc:get-current-book))
+ (gnc:query-set-match-non-voids-only! query (gnc:get-current-book))
+ (gnc:query-set-sort-order query
+ (list gnc:split-trans gnc:trans-date-posted)
+ (list gnc:query-default-sort)
+ '())
+ (gnc:query-set-sort-increasing query #t #t #t)
+ ;; set the "__reg" options required by the Register Report...
+ (for-each
+ (lambda (l)
+ (set-option! "__reg" (car l) (cadr l)))
+ ;; One list per option here with: option-name, default-value
+ (list
+ (list (N_ "query") (gnc:query->scm query)) ;; think this wants an scm...
+ (list (N_ "journal") #t)
+ (list (N_ "double") #t)
+ (list (N_ "debit-string") (N_ "Debit"))
+ (list (N_ "credit-string") (N_ "Credit"))
+ )
+ )
+ ;; we'll leave query malloc'd in case this is required by the C side...
+
+ ;; set options in the general tab...
+ (set-option!
+ gnc:pagename-general (N_ "Title") (N_ "General Journal"))
+ ;; we can't (currently) set the Report name here
+ ;; because it is automatically set to the template
+ ;; name... :(
+
+ ;; set options in the display tab...
+ (for-each
+ (lambda (l)
+ (set-option! gnc:pagename-display (car l) (cadr l)))
+ ;; One list per option here with: option-name, default-value
+ (list
+ (list (N_ "Date") #t)
+ (list (N_ "Num") #f)
+ (list (N_ "Description") #t)
+ (list (N_ "Account") #t)
+ (list (N_ "Shares") #f)
+ (list (N_ "Price") #f)
+ ;; note the "Amount" multichoice option here
+ (list (N_ "Amount") 'double)
+ (list (N_ "Running Balance") #f)
+ (list (N_ "Totals") #f)
+ )
+ )
+
+ options)
+ )
+
+;; report renderer
+
+(define (general-journal-renderer report-obj)
+ ;; just delegate rendering to the Register Report renderer...
+ ((gnc:report-template-renderer/name regrptname) report-obj))
+
+(gnc:define-report
+ 'version 1
+ 'name reportname
+ 'menu-path (list gnc:menuname-asset-liability)
+ 'options-generator general-journal-options-generator
+ 'renderer general-journal-renderer
+ )
+
+;; END
+
More information about the gnucash-changes
mailing list