#!/usr/bin/perl
# csv2abo - converts CSV files to the ABO-KB format for mass-payment, used by Czech banks
# Copyright (C) 2007 Jiri Bohac
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.


# csv2abo - prevadi csv (comma separated values) soubory na hromadne prikazy
#           k uhrade ve formatu ABO-KB


################# Nastaveni #########################################

$nazev = "ACME s.r.o.";
$cislo_klienta = 1234;
$cislo_uctu_prikazce = "1234567890";
$kod_banky = 1234;

$sloupec_cislo_uctu = 29; #sloupec obsahujici cislo uctu prijemce
$sloupec_castka = 32;  	#sloupec obsahujici castku
$sloupec_vs = 0;  	#sloupec obsahujici variabilni symbol (0 = variabilni sybol 9)
$sloupec_podminka = 32;	#sloupec, ktery urcuje zda je radek platny, pomoci hodnot 0 nebo 1 (0 = zadna podminka)
$sloupec_zprava = 0;	#sloupec se zpravou pro prijemce (0 = zadna zprava)
$preskocit_radek = 2;	#pocet radek s hlavickami, ktere neobsahuji spravne formatovana data
$splatnost_od_ted = 24 * 3600;	#datum zplatnosti ve vterinach od aktualniho casu

################# Konec Nastaveni ###################################

# tiskni UHL 

($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
$date = sprintf("%02d%02d%02d", $mday, $mon + 1, $year - 100);

($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time + $splatnost_od_ted);
$date2 = sprintf("%02d%02d%02d", $mday, $mon + 1, $year - 100);

$cislo_klienta = sprintf("%010.10s", $cislo_klienta);
$nazev = sprintf("%-20.20s", $nazev);
print("UHL1${date}${nazev}${cislo_klienta}001999\r\n");

# tiskni hlavicku ucetniho souboru

$kod_banky = sprintf("%04.4s", $kod_banky);
print("1 1501 001000 $kod_banky\r\n");


# jednotlive radky ze vstupu
$group_total = 0;
$line_cnt = 0;
@group = ();

while ($line= <STDIN>) {
	++$line_cnt;
	if ($line_cnt <= $preskocit_radek) {
		next;
	}

	$line =~ s/"//g;
	chop($line);
	@fields = split("[ \t]*,[ \t]*", $line);
	
	($ucet, $banka) = split("/", @fields[$sloupec_cislo_uctu - 1]);
	$castka = @fields[$sloupec_castka - 1];
	$variabilni_symbol = $sloupec_vs ? @fields[$sloupec_vs - 1] : 9;
	$podminka = $sloupec_podminka ? @fields[$sloupec_podminka - 1] : 1;
	$zprava = $sloupec_zprava ? @fields[$sloupec_zprava - 1] : "";
	$zprava =~ s/[^a-zA-Z]//g;
	$zprava = "AV:$zprava";
	$castka =~ s/,/./g;	
	$spec_symbol = "0000000000";
	
	if (!$podminka) { 
		next; 
	}
	
	if (!($castka > 0)) {
		die ("Neplatna castka ($castka) na radku $line_cnt ($zprava)\n") 
	}

	if (index($ucet, "-") >= 0) {
		($predcisli, $ucet) = split("-", $ucet);
	}
	else {
		$predcisli = 0;
	}

	if ($ucet == 0 || $banka == 0 || $ucet > 10000000000 ) {
		die ("Spatne cislo uctu (@fields[$sloupec_cislo_uctu - 1] = $predcisli -- $ucet/$banka) na radku $line_cnt ($zprava)\n");
	}

	if (modulo11($ucet)) {
		die ("Spatne cislo uctu ($ucet) na radku $line_cnt ($zprava)\n");
	}

	if (modulo11($predcisli)) {
		die ("Spatne predcisli uctu ($predcisli) na radku $line_cnt ($zprava)\n");
	}


	$ucet = sprintf("%06.0f-%010.0f", $predcisli, $ucet);
	$group_total += $castka;
	$castka = sprintf("%012.12u", $castka * 100);
	$variabilni_symbol = sprintf("%010.10d", $variabilni_symbol);
	$konstatnti_symbol = sprintf("%04.4d0138", $banka);

	push(@group, sprintf("$ucet $castka $variabilni_symbol $konstatnti_symbol $spec_symbol $zprava\r\n"));

	if (@group == 10) {
		print_group(\@group, $group_total);
		@group = ();
		$group_total = 0;
	}

}

if (@group > 0) {
	print_group(\@group, $group_total);
}

# tiskni konec ucetniho souboru

$kod_banky = sprintf("%04.4s", $kod_banky);
print("5 +\r\n");



sub print_group {
	($group, $total) = @_;
	$total = sprintf("%014.14u", $total * 100);
	print("2 $cislo_uctu_prikazce $total $date2\r\n");
	print(@$group);
	print("3 +\r\n");
}

sub modulo11 {
	($cislo) = @_;
	@a = reverse(split("", $cislo));
	@k = (1, 2, 4, 8, 5, 10, 9, 7, 3, 6);

	$total = 0;
	for ($count = 0; $count < @a; ++$count) {
		$total+= @a[$count] * @k[$count];
	}

	return $total % 11;
}

