file format
Jason Rennie
jrennie@ai.mit.edu
Sun, 25 Mar 2001 11:42:10 -0500
This is a multipart MIME message.
--==_Exmh_-17602499250
Content-Type: text/plain; charset=us-ascii
Hi Dave,
dave@krondo.com said:
> But since you're using perl, you might check out the perl interface
> that comes with GnuCash 1.4.x. It is used by gnc-prices. You don't
> have to parse anything :)
Thanks again for the pointer. It was a breeze to go from the gnc-prices
script to a report-producing perl script. :) I'm including the script
that I've produced in case anyone else is looking for something like what
I wanted.
Jason
--==_Exmh_-17602499250
Content-Type: text/plain ; name="gnc-report.perl"; charset=us-ascii
Content-Description: gnc-report.perl
Content-Disposition: attachment; filename="gnc-report.perl"
#!/usr/bin/perl -w
# Produce average monthly expenditures by category
# Written by Jason Rennie <jrennie@ai.mit.edu>, March 2001
use lib '/usr/share/gnucash/perl';
use lib '/usr/lib/gnucash/perl';
use gnucash;
use strict;
my $gncFile;
my (undef, undef, undef, $mday, $month, $year, undef, undef, undef) =
localtime (time);
$year += 1900;
$month++;
my $endDay = $mday;
my $endMonth = $month;
my $endYear = $year;
my $startDay = $endDay;
my $startMonth = $endMonth;
my $startYear = $endYear-1;
my $defaultExpr = 1;
my @acctExpr = ("Liabilites:Loans",
"Expenses");
parseArgs(@ARGV);
my $months = monthDiff ($startMonth, $startYear, $endMonth, $endYear);
my $startTime = gnucash::xaccDMYToSec ($startDay, $startMonth, $startYear);
my $endTime = gnucash::xaccDMYToSec ($endDay, $endMonth, $endYear);
die "End time before start time" if ($endTime < $startTime);
print "Date: $month/$mday/$year\n";
print "Period: $startMonth/$startDay/$startYear to $endMonth/$endDay/$endYear\n";
print "Months: $months\n";
# open the file, read all of the accounts
my $sess = gnucash::xaccMallocSession ();
my $grp = gnucash::xaccSessionBeginFile ($sess, $gncFile);
die "failed to read file $ARGV[0], maybe its locked? " if (! $grp);
# get a flat list of accounts in the file
my @acctlist = &accountList ($grp);
printf "%50s Monthly # trans\n\n", "Account";
# loop over the accounts, look for stock and mutual funds.
foreach my $acct (@acctlist)
{
my $match = 0;
my $name = gnucash::xaccAccountGetFullName ($acct, ":");
foreach my $expr (@acctExpr) {
$match = 1 if ($name =~ m/$expr/i);
}
#print $name, "\n";#
#next;#
next if (!$match);
my $sCount = gnucash::xaccAccountGetNumSplits ($acct);
my $sum = 0;
for (my $si=0; $si < $sCount; $si++) {
my $split = gnucash::xaccAccountGetSplit ($acct, $si);
my $trans = gnucash::xaccSplitGetParent ($split);
my $time = gnucash::xaccTransGetDate ($trans);
next if ($time < $startTime or $time > $endTime);
my $value = gnucash::xaccSplitGetValue ($split);
$sum += $value;
}
next if ($sum < 1 and $sum > -1);
$sum /= $months;
printf "%50s \$%7.2f %d\n", $name, int($sum*100)/100, $sCount;
}
gnucash::xaccSessionEnd ($sess);
sub accountList
{
my ($grp) = @_;
my $naccts = gnucash::xaccGroupGetNumAccounts ($grp);
my @acctlist;
for (my $n=0; $n < $naccts; $n++) {
my @foo = gnucash::xaccGetAccounts ($grp);
my $acct = gnucash::xaccGroupGetAccount ($grp, $n);
push @acctlist, $acct;
if (my $children = gnucash::xaccAccountGetChildren ($acct)) {
my @childlist = accountList ($children);
push @acctlist, @childlist;
}
}
return (@acctlist);
}
sub monthDiff
{
my ($monthStart, $yearStart, $monthEnd, $yearEnd) = @_;
die "Start date must be before end date"
if ($yearStart > $yearEnd
or ($yearStart == $yearEnd and $monthStart > $monthEnd));
my $diff = $monthEnd - $monthStart;
$diff += ($yearEnd - $yearStart)*12;
return $diff;
}
sub parseArgs
{
while ($_ = shift) {
if ($_ eq "-h" or $_ eq "-?") {
usage();
} elsif ($_ eq "-m") {
my $span = shift;
die "Argument to -m must be > 0" if ($span <= 0);
$startYear = $endYear+int(($endMonth - $span - 12)/12);
$startMonth = $endMonth+12*($endYear-$startYear)-$span;
} elsif ($_ eq "-e") {
my $date = shift;
die "Wrong date format given to -e" if (!(my ($month, $mday, $year) = ($date =~ m,(\d+)/(\d+)/(\d+),)));
$endMonth = $month;
$endDay = $mday;
$year += 1900 if ($year > 50 and $year < 100);
$year += 2000 if ($year <= 50);
$endYear = $year;
} elsif ($_ eq "-s") {
my $date = shift;
die "Wrong date format given to -s" if (!(my ($month, $mday, $year) = ($date =~ m,(\d+)/(\d+)/(\d+),)));
$startMonth = $month;
$startDay = $mday;
$year += 1900 if ($year > 50 and $year < 100);
$year += 2000 if ($year <= 50);
$startYear = $year;
} elsif ($_ eq "-r") {
my $regex = shift;
if ($defaultExpr) {
@acctExpr = ($regex);
$defaultExpr = 0;
} else {
push @acctExpr, $regex;
}
} else {
if (!defined($gncFile)) {
$gncFile = $_;
} else {
usage();
}
}
}
if (!defined($gncFile)) {
print STDERR "<gnucash-filename> required.";
usage();
}
}
sub usage
{
print STDERR "$0 [options] <gnucash-filename>\n";
print STDERR "\n";
print STDERR "\t-m NUM\tNumber of months to span.\n";
print STDERR "\t-e MM/DD/YYYY\tEnding date.\n";
print STDERR "\t-s MM/DD/YYYY\tStarting date.\n";
print STDERR "\t-r EXPR\tRegular expression for matching account name.\n";
print STDERR "\t\tUse -r multiple times for multiple expressions.\n";
exit(1);
}
--==_Exmh_-17602499250--