#!/usr/bin/perl

use strict;
use warnings;

# 20030513 - Initial creation

# Script to generate Quicken compatible QIF files using CSV output from
# SouthTrust.com.  Categories are also quite absent, so I add my own.

# This map is keyed on the extracted payee name, which is quite useless
# and thus is replaced with the values within the array associated with
# each key.  The first element is the real payee and the second element
# is the correct category.  This won't work when a particular payee
# can fall under multiple categories; My financial life isn't that busy.

# Anything that's a cheque gets a check number, but no Payee name.
# Since the only cheque I ever write is for rent, I just fudge it.

# These are some sample entries.  The hash key is the name of the
# business that charged you as it appears in the CSV export.
# The anonymous array's two values are the company name as you
# wish it to appear in Quicken[0] and the category name as it
# appears in Quicken, including a colon between subcategories[1].

# Here's an example from a recent CSV export I did for Staples.
# Match up the fields with %map below and what I do in the
# code and you can take it from here.

# 08/05/2003,CkCd STAPLES #235 ALA FL,,-$90.89,,

my %map = (
	'cheque' => [
		'Company That Owns Me',
		'Rent'
	],
	'DEPOSIT' => [
		'Deposit',
		'Deposit'
	],
	'GLEIM PUB GLEIM PAY' => [
		'Gleim Publications',
		'Salary'
	],
	'SERVICE CHARGE' => [
		'South Trust',
		'Bank Charge'
	],
	'CHECK CARD MONTHLY FEE' => [
		'South Trust',
		'Bank Charge'
	],
	'ATM SHARED NETWORK FEE' => [
		'South Trust',
		'Bank Charge'
	],
	'CkCd STAPLES #235 ALA FL' => [
		'Staples',
		'Computer:Components'
	],
	'CkCd OFFICE MAX 0 5-885-0828 FL' => [
		'Office Max',
		'Computer:Components'
	],
	'CkCd REGAL CINEMAS G INESVILLE FL' => [
		'Regal Cinemas',
		'Entertainment:Theater'
	]

);

print "!Type:Bank\r\n";

# Skip the first line
my $line = <STDIN>;
undef $line;

# We want to suck in each record, which is ^\r\n terminated.
#$/ = "^\r\n";

while( my $rec = <STDIN> ) {

#	my @chars = split( '', $rec );
#	foreach my $z (@chars) {
#		print "' $z ' " . ord( $z ), "\n";
#	}
#	last;

	my( $date, $desc, $checkn, $dt, $cr, undef ) = split( /,/, $rec );

#D4/30/99
#U1,156.20
#T1,156.20
#CX
#POpening Balance
#L[Checking]
#^

	my $amount;
	if( $dt ne '' ) {
		$amount = $dt;
	}
	elsif( $cr ne '' ) {
		$amount = $cr;
	}
	else { $amount = 0; }

	# If it's NULL it's a cheque; If I wrote more of these I'd
	# probably need to figure out the Payee based on amount if
	# it is recurring or just make up a guess.

	if( $desc eq '' ) {
		$desc = 'cheque';
	}

	# If it exists in our map, replace SouthTrust's values with our
	# own custom values.  If we don't have a map entry, we
	# need $cat to simply be empty.

	my( $payee, $cat );
	if( exists $map{ $desc } ) {
		$payee = $map{ $desc }[0];
		$cat = "L";
		$cat .= $map{ $desc }[1];
		$cat .= "\r\n";
	}
	else {
		$payee = $desc;
		$cat = '';
		warn "$desc has no map entry!\n";
	}

	print "D$date\r\nU$amount\r\nP$payee\r\n$cat^\r\n";

}

