#!/usr/bin/perl
#  ave-by-cat.pl - Prints a report of monthly average by category.
#
#  Written by Curtis Olson.  Started November 12, 1994.
#
#  Copyright (C) 1994 - 1997  Curtis L. Olson  - curt@sledge.mn.org
#
#  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, write to the Free Software
#  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

# $Id: ave-by-cat.pl,v 2.5 1997/04/23 18:06:22 curt Exp $
# (Log is kept at end of this file)


package CBB;

use strict;    # don't take no guff


my($tmp, $temp, $cbb_incl_dir);
my($account, @account_list, $name, $trans, %ALLTRANS);
my($todate, $fromdate, $firstdate, $lastdate);
my($firstday, $firstmon, $firstyear, $lastday, $lastmon, $lastyear);
my($totalmonths);
my($key, $date, $check, $desc, $debit, $credit, $cat, $com, $cleared, $total);
my($amt, $result, $totalcredit, $totaldebit);
my($splits, @splits, $tamt, $tcat, $tcom);


# return the directory of a file name (this is duplicated in common.pl
# but we need this to find the include directory for common.pl :-(
sub my_file_dirname {
    my($file) = @_;
    my($pos);

    $pos = rindex($file, "/");
    if ( $pos >= 0 ) {
	return substr($file, 0, ($pos + 1));
    } else { 
	return "./"; 
    }
}

# specify the installed location of the necessary pieces.
$temp = &my_file_dirname($0); chop($temp);
$cbb_incl_dir = &my_file_dirname($temp);
unshift(@INC, $cbb_incl_dir);

require "common.pl";
require "reports.pl";
require "engine.pl";
require "memorized.pl";


($#ARGV >= 0) || die "Usage: report [ -from date ] [ -to date] accounts";


# process arguments

($fromdate, $todate, @account_list) = &process_rep_args();

if ( $fromdate eq "all" ) {
    $fromdate = "";
}

if ( $todate eq "all" ) {
    $todate = "";
}

# print "'$fromdate' '$todate' '@account_list'\n";

%ALLTRANS = ();

# load all matching transactions from all specified accounts (ignoring
# those that are outside the specified date range)

my(%tmp_cat) = ();
$firstdate = "";
$lastdate = "";

foreach $account ( @account_list ) {
    $name = &file_basename($account);

    # open the account
    (&load_trans($account) eq "ok") || die "Cannot open account:  $account";

    $result = &first_trans();
    while ( $result ne "none" ) {
        ($key, $date, $check, $desc, $debit, $credit, $cat, $com, $cleared,
         $total) = split(/\t/, $result);

        $amt = $credit - $debit;

        if ( (($fromdate == 0) || ($fromdate <= $date)) && 
            (($todate == 0) || ($todate >= $date)) ) {

	    if ( ($firstdate eq "") || ($date < $firstdate) ) {
	        $firstdate = $date;
	    }

	    if ( ($lastdate eq "") || ($date > $lastdate) ) {
	        $lastdate = $date;
	    }

            if ( substr($cat, 0, 1) ne "|" ) {
                $tmp_cat{$cat} += $amt;
		$totalcredit += $credit;
		$totaldebit += $debit;
            } else {
                # process split

                @splits = split(/\|/, $cat);
                shift(@splits);

                $tmp = 0;
                while ( $#splits >= 0 ) {
                    $tcat = shift(@splits);
                    $tcom = shift(@splits);
                    $tamt = shift(@splits);

                    $tmp += $tamt;

                    # print "processing $tcat $tamt\n";
                    $tmp_cat{$tcat} += $tamt;
		    if ( $tamt > 0 ) {
			$totalcredit += $tamt;
		    } else {
			$totaldebit -= $tamt;
                    }
                }
                if ( sprintf("%.2f", $tmp) ne sprintf("%.2f", $amt) ) {
                    printf("WARNING:  Incorrect splits in $date: $desc\n");
                    printf("    %.2f != %.2f\n\n", $tmp, $amt);
                }
            }
        }

        $result = &next_trans();
    }
}


if ( ($lastdate < $firstdate) || ($lastdate eq "") || ($firstdate eq "") ) {
    die "Problem with date range.  from '$firstdate' to '$lastdate'.\n";
}

# determine number of months in range
($firstyear,$firstmon,$firstday) = $firstdate =~ /(\d\d\d\d)(\d\d)(\d\d)/;
($lastyear,$lastmon,$lastday) = $lastdate =~ /(\d\d\d\d)(\d\d)(\d\d)/;

$totalmonths = ($lastyear - $firstyear) * 12;
$totalmonths += ($lastmon - $firstmon);
$totalmonths++;

print "Average Monthly Expenses by category for $firstmon/$firstday/$firstyear".
      " to $lastmon/$lastday/$lastyear.\n";
print "    (Range is $totalmonths months.)\n";
print "\n";

foreach $cat (sort keys(%tmp_cat)) {
    printf("%35s  = %10.2f\n", $cat, $tmp_cat{$cat} / $totalmonths);
}

print "\n";

printf("Total Monthly Average Income   = %.2f\n", $totalcredit / $totalmonths);
printf("Total Monthly Average Expenses = %.2f\n", $totaldebit / $totalmonths);

# ----------------------------------------------------------------------------
# $Log: ave-by-cat.pl,v $
# Revision 2.5  1997/04/23 18:06:22  curt
# Fixed a missing "require"
#
# Revision 2.4  1997/01/28 03:25:47  curt
# Force strict scoping in all perl scripts.
#
# Revision 2.3  1996/12/17 14:54:14  curt
# Updated copyright date.
#
# Revision 2.2  1996/12/13 01:25:52  curt
# Modified paths.  Updated to work with reports.tcl
#
# Revision 2.1  1996/10/22 21:42:47  curt
# Initial revision
#
