#!/usr/bin/perl
#
#  mym_to_cbb.pl -  Using MYM's report format, migrate data in an
#                   MYM report to a format readable by CBB.  Tested
#                   only with MYM Windows Version 2.
#
#  Try 'perldoc mym_to_cbb.pl' for more details (or go to the end of
#  this script).
#
#  Written by Brian A. Koontz
#
#  Copyright (C) 1999 Brian A. Koontz (briank@hex.net)
#
#  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: mym_to_cbb.pl,v 1.1.1.1 1999/12/18 02:06:07 curt Exp $
#  Revision logs at end of file.
#

$filename = $ARGV[0];
$root = $filename;
$root =~ /(\w*)\./;
$root = $1;
open( INPUT, "<$filename" ) || die "$filename could not be opened\n";
if( -e "${root}.cbb" ) {
  $outfile = $root."~.cbb";
}
else {
  $outfile = $root.".cbb";
}
open( OUTPUT, ">$outfile" );

use Cwd;
$dir = cwd();
print OUTPUT "# CBB Data File -- ${dir}/${outfile}\n"; 
print OUTPUT "#\n";
print OUTPUT "# CBB Version = 0.74\n";
print OUTPUT "# Current Balance = 0.00\n";
print OUTPUT "# Ending Balance = 0.00\n";
print OUTPUT "# Transaction Count = 0\n";
print OUTPUT "# Cleared Balance = 0.00\n";
print OUTPUT "# Cleared Txn Count = 0\n";
$todayDate = eval((localtime)[4]+1)."/".(localtime)[3]."/".(localtime)[5];
$user = (getpwuid($<))[0];
print OUTPUT "# Saved on (US Date Fmt) ${todayDate} by ${user}\n";
print OUTPUT "#\n";
print OUTPUT "# date  check  desc  debit  credit  cat  com  cleared\n";
print OUTPUT "# ---------------------------------------------------\n"; 

#
# Parse column headers
#
while( <INPUT> ) {
  if( !( /Date/ ) ) { next; }
  ( @headingFields ) = split;
  my $heading;
  foreach $heading( @headingFields ) {
    $headingMap{ "$heading" } = 0;
  }
  $_ = <INPUT>;
  ( @headingLengths ) = split;
  my( $count ) = 0;
  foreach $heading( @headingFields ) {
    $headingMap{ "$heading" } = length( $headingLengths[ $count ] );
    $count++;
  }
  last;
}

#
# Check for necessary fields in headingMap
#
if( !( exists( $headingMap{ "Date" } ) ) ||
    !( exists( $headingMap{ "ID" } ) ) ||
    !( exists( $headingMap{ "Payee" } ) ) ||
    !( exists( $headingMap{ "Amount" } ) ) ) {
  print STDERR "***Fatal error***\n";
  print STDERR "The Date, ID, Payee, and Amount fields must be included\n";
  print STDERR "in the MYM report format.  Please check your report generation\n";
  print STDERR "filters in MYM, and ensure, at a minimum, the above four\n";
  print STDERR "fields are included in your report output.\n";
  close( OUTPUT );
  unlink( $outfile );
  exit( 1 );
}

#
# Transfer input lines to output file
#
while( <INPUT> ) {
  if( /Beginning Balance/ )
  {
     /Beginning Balance\s+([-\.,\d]+)/;
     my $val = $1;
     $val =~ s/,//g;
     print OUTPUT "\t\t\t0.00\t$val\n";
     next;
  }
  if( !( /\/+/ ) ) { next; }    # Next line if no date slashes
  my( @fields ) = split;
  if( $#fields <= 2 ) { next; }
  #
  # Get fields
  #
  my $heading;
  my $fieldValue;
  my $count = 0;
  my $nextCol = 0;  
  my %value;
  foreach $heading( @headingFields ) {
    if( $heading eq "Amount" ) {
      $fieldValue = substr( $_, $nextCol, length( $headingLengths[ $count ] ) );
      $fieldValue =~ s/\s+//;
      $fieldValue =~ s/\,//;
    }
    elsif( $heading eq "Clr" ) {
      $fieldValue = substr( $_, $nextCol, length( $headingLengths[ $count ] ) );
      $fieldValue =~ s/\s+//g;
    }
    else {
      ( $fieldValue ) = split( /\s{2,}/, substr( $_, $nextCol, length( $headingLengths[ $count ] ) ) );
    }
    $value{ "$heading" } = $fieldValue;
    $nextCol += length( $headingLengths[ $count++ ] ) + 2;
  }
  $value{ "Date" } = &convertDate( $value{ "Date" } ); 
  if( exists( $value{ "Category" } ) ){
    $value{ "Category" } =~ s/(\[.*)/\#$1\#/; # Hide [] from cbb
    $categories{ $value{"Category"}} = "";
  }
  if( $value{ "Amount" }  < 0.0 ) {
    $debit = $value{ "Amount" } * -1.0;
    $credit = 0.0;
  }
  else {
    $debit = 0.0;
    $credit = $value{ "Amount" };
  }
  if( exists( $value{ "Clr" } ) ) {
    if( $value{ "Clr" } eq "R" ) {
      $value{ "Clr" } = "x";
    }
    elsif( $value{ "Clr" } eq "C" ) {
      $value{ "Clr" } = "*";
    }
    else {
      $value{ "Clr" } = "";
    }
  }
  #
  # cbb output line: date check desc debit credit cat com clrd
  #
  print OUTPUT  "$value{ 'Date'}\t",
                "$value{ 'ID' }\t",
                "$value{ 'Payee' }\t",
                "$debit\t",
                "$credit\t",
                "$value{ 'Category' }\t",
                "$value{ 'Memo' }\t",
                "$value{ 'Clr' }\n";
}

close( OUTPUT );

#
#  Output categories to categories file
#  by reading in original file and adding this process'
#  hash of categories, eliminating duplicates.
#

open( INPUT, "<categories" );
while( <INPUT> )
{
   next if /^\s+/; # Next on blank line
   chop;
   my( $cat, $desc ) = split( "\t", $_ );
   $categories{$cat} = $desc;
}

close( INPUT );
open( OUTPUT, ">categories" );

foreach $key( sort keys %categories )
{
   print OUTPUT "$key\t$categories{$key}\n";
}

close( OUTPUT );

sub convertDate {
  local( $dateString ) = @_;
  $dateString =~ /(\w*)\/(\w*)\/(\w*)/;
  return $3.$1.$2;
}

=head1 NAME

mym_to_cbb.pl - Converts MYM (Managing Your Money) export files to CBB
files for import.

=head1 DESCRIPTION

Migrate data in an MYM report to a format readable by CBB.  Tested
only with MYM Windows Version 2. Your mileage may vary with other
versions.  

=head1 SYNTAX

B<mym_to_cbb.pl [filename]>

where B<filename> is the name of the MYM export file to convert.
Output will be written to a file with the same filename root and the
extension "B<cbb>".  If a file of that name already exists,
"B<filename~.cbb>" will be written.  If both exist, nothing will be
written.

A file called B<categories> will also be generated (or, if one exists,
new non-duplicated entries will be merged with existing entries). 

=head1 NOTES

=over 4

=item *

A minimum set of exported fields are required in the MYM export file.
Within MYM, invoke the export function from the toolbar menu: 
"B<Reports~Transaction~Bank-by Account>". Sort by B<Account>, and
ensure B<Subtotal>, B<Clear status>, B<Number/ID>, B<Categories>,
B<Memos>, and B<Running balance> are selected.

=item *

Include only one account in each export file. The script will not
correctly parse multiple accounts in the same export file.

=item *

In MYM and CBB, the B<[]> characters surround account names which are
automatically debited or credited according to the transaction type.
For expediency's sake, these have been disable during import to CBB by
surrounding the brackets with the B<#> character.  Once all the
appropriate accounts have been set up under CBB, you should be able to
use your favorite editor to change the B<#[> and B<]#> character pairs
back to B<[]> in each account file, ensuring correct adjustment of
accounts.  This hasn't been tested, so I'd appreciate feedback on
this.

=back

=head1 AUTHOR

Brian A. Koontz <briank@hex.net>

=cut

#
# $Log: mym_to_cbb.pl,v $
# Revision 1.1.1.1  1999/12/18 02:06:07  curt
# Start of 0.8 branch
#
# Revision 1.1  1999/12/17 19:21:02  curt
# Added to repository.
#
# Revision 2.1  1999/01/13 22:40:31  curt
# Fixed a small bug in import_qif() relating to the logic of properly
# reconstructing splits.
#
# Added a script to convert MYM files to CBB.  Contributed by Brian
# <briank@hex.net>
#
# Added an Emacs "edb" interface to the contrib section.  Provided by
# Bob Newell <bnewell@alum.mit.edu>
#
# Preserve owner, group, and permissions of CBB files
#
# Added a loan_recur.pl script from Michel Verdier which does the same
# thing as loan.pl, but also generates recuring transactions for the
# payments.
#
# Patch from Michel Verdier to help recur.pl better handle recurring
# transfer transactions.
#
# Added initial support for binding an arbitrary math function to the
# debit and credit fields in the main transaction editor section.  This
# is useful for doing things like currency conversions.  You can enter
# in one currency and then use a hot key to convert to your "canonical"
# currency.
#
# Revision 1.3  1999/01/08 05:32:30  brian
# Correctly parses beginning/ending balance, other
# minor changes
#
# Revision 1.2  1997/12/24 06:22:55  brian
# Made parsing routine more robust by using fixed-field
# lengths rather than splits.  Added support for reconciled
# and cleared transactions.  Added GNU license info, disclaimer.
#
# Revision 1.1  1997/12/23 20:56:17  brian
# Initial revision
#
#
      
     
  

