| 
									
										
										
										
											2011-10-12 17:26:19 -04:00
										 |  |  | #!/usr/bin/perl | 
					
						
							|  |  |  | # trail-balance-report.plx                                    -*- Perl -*- | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | #    Script to generate a Trial Balance report for a ledger. | 
					
						
							| 
									
										
										
										
											2011-10-12 17:27:25 -04:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											2011-10-12 17:26:19 -04:00
										 |  |  | # Copyright (C) 2011, Bradley M. Kuhn | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # This program gives you software freedom; you can copy, modify, convey, | 
					
						
							|  |  |  | # and/or redistribute it under the terms of the GNU General Public License | 
					
						
							|  |  |  | # as published by the Free Software Foundation; either version 3 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 in a file called 'GPLv3'.  If not, write to the: | 
					
						
							|  |  |  | #    Free Software Foundation, Inc., 51 Franklin St, Fifth Floor | 
					
						
							|  |  |  | #                                    Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-20 09:23:35 -04:00
										 |  |  | # ledger --wide-register-format "%-.70A %22.108t\n" -f no-fund.ledger -b 2010/03/01 -e 2011/03/01 -w reg | 
					
						
							| 
									
										
										
										
											2011-10-12 17:57:20 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-12 17:28:04 -04:00
										 |  |  | use strict; | 
					
						
							|  |  |  | use warnings; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-12 17:27:25 -04:00
										 |  |  | use Math::BigFloat; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-12 17:26:19 -04:00
										 |  |  | my $LEDGER_CMD = "/usr/bin/ledger"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-02 07:21:49 -05:00
										 |  |  | my $ACCT_WIDTH = 75; | 
					
						
							| 
									
										
										
										
											2011-10-12 17:26:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-12 17:57:20 -04:00
										 |  |  | # http://www.moneyinstructor.com/lesson/trialbalance.asp | 
					
						
							|  |  |  | # told me: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Key to preparing a trial balance is making sure that all the account | 
					
						
							|  |  |  | # balances are listed under the correct column.  The appropriate columns | 
					
						
							|  |  |  | # are as follows: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Assets = Debit balance | 
					
						
							|  |  |  | # Liabilities = Credit balance | 
					
						
							|  |  |  | # Expenses = Debit Balance | 
					
						
							|  |  |  | # Equity = Credit balance | 
					
						
							|  |  |  | # Revenue = Credit balance | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # So, there are some sign switches that are needed: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-12 17:26:19 -04:00
										 |  |  | sub ParseNumber($) { | 
					
						
							|  |  |  |   $_[0] =~ s/,//g; | 
					
						
							|  |  |  |   return Math::BigFloat->new($_[0]); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Math::BigFloat->precision(-2); | 
					
						
							|  |  |  | my $ZERO =  Math::BigFloat->new("0.00"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if (@ARGV == 0) { | 
					
						
							|  |  |  |   print STDERR "usage: $0 <LEDGER_OPTIONS>\n"; | 
					
						
							|  |  |  |   exit 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-02 07:21:49 -05:00
										 |  |  | my(@ledgerOptions) = ('--wide-register-format', "%-.${ACCT_WIDTH}A %22.108t\n",  '-w', | 
					
						
							|  |  |  |                       @ARGV, 'reg'); | 
					
						
							| 
									
										
										
										
											2011-10-12 17:26:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-02 07:21:49 -05:00
										 |  |  | open(LEDGER_DATA, "-|", $LEDGER_CMD, @ledgerOptions) | 
					
						
							|  |  |  |   or die "Unable to run $LEDGER_CMD @ledgerOptions: $!"; | 
					
						
							| 
									
										
										
										
											2011-10-12 17:26:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | my %acct; | 
					
						
							| 
									
										
										
										
											2011-12-02 07:21:49 -05:00
										 |  |  | while (my $line = <LEDGER_DATA>) { | 
					
						
							| 
									
										
										
										
											2011-10-12 17:57:20 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-02 07:21:49 -05:00
										 |  |  |   die "Unable to parse output line from negative_ledger command: $line" | 
					
						
							|  |  |  |     unless $line =~ /^\s*([^\$]+)\s+\$\s*\s*([\-\d\.\,]+)/; | 
					
						
							| 
									
										
										
										
											2011-10-12 17:26:19 -04:00
										 |  |  |   my($account, $amount) = ($1, $2); | 
					
						
							|  |  |  |   $amount = ParseNumber($amount); | 
					
						
							|  |  |  |   $account =~ s/^\s+//;    $account =~ s/\s+$//; | 
					
						
							| 
									
										
										
										
											2011-12-02 07:21:49 -05:00
										 |  |  |   $acct{$account}{debit} = $ZERO if not defined $acct{$account}{debit}; | 
					
						
							|  |  |  |   $acct{$account}{credit} = $ZERO if not defined $acct{$account}{credit}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ($account =~ /^(Asset|Expense)/) { | 
					
						
							|  |  |  |       $acct{$account}{debit} += $amount; | 
					
						
							|  |  |  |   } elsif ($account =~ /^(Income)/) { | 
					
						
							|  |  |  |     $acct{$account}{debit} += - $amount; | 
					
						
							|  |  |  |   } elsif ($account =~ /^(Liabilities)/) { | 
					
						
							|  |  |  |     $acct{$account}{credit} += $amount; | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     die "unkown account type $account"; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-10-12 17:26:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2011-12-02 07:21:49 -05:00
										 |  |  | close LEDGER_DATA; | 
					
						
							|  |  |  | die "error($0): $! while running ledger command line" unless ($? == 0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-12 17:26:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-12 17:57:20 -04:00
										 |  |  | print sprintf("%-${ACCT_WIDTH}.${ACCT_WIDTH}s        %s              %s\n\n", "ACCOUNT", "DEBITS", "CREDITS"); | 
					
						
							| 
									
										
										
										
											2011-10-12 17:26:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-12 17:57:20 -04:00
										 |  |  | my $format = "%-${ACCT_WIDTH}.${ACCT_WIDTH}s       \$%11.2f       \$%11.2f\n"; | 
					
						
							|  |  |  | my($totDeb, $totCred) = ($ZERO, $ZERO); | 
					
						
							|  |  |  | foreach my $account (sort keys %acct) { | 
					
						
							|  |  |  |   foreach my $val (qw/debit credit /) { | 
					
						
							| 
									
										
										
										
											2011-10-12 17:26:19 -04:00
										 |  |  |     $acct{$account}{$val} = $ZERO unless defined $acct{$account}{$val}; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-10-12 17:57:20 -04:00
										 |  |  |   print sprintf($format, $account, | 
					
						
							|  |  |  |                 $acct{$account}{debit},                 $acct{$account}{credit}); | 
					
						
							|  |  |  |   $totDeb += $acct{$account}{debit}; | 
					
						
							|  |  |  |   $totCred += $acct{$account}{credit}; | 
					
						
							| 
									
										
										
										
											2011-10-12 17:29:34 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-12 17:26:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2011-10-12 17:57:20 -04:00
										 |  |  | print "\n\n", sprintf($format, 'TOTAL', $totDeb, $totCred); | 
					
						
							| 
									
										
										
										
											2011-10-12 17:26:19 -04:00
										 |  |  | ############################################################################### | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Local variables: | 
					
						
							|  |  |  | # compile-command: "perl -c trial-balance-report.plx" | 
					
						
							|  |  |  | # End: | 
					
						
							|  |  |  | 
 |