#!/usr/bin/perl -Tw
#
#  LMS version 1.11.7 Bastet
#
#  Copyright (C) 2001-2009 LMS Developers
#
#  Please, see the doc/AUTHORS for more information about authors!
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License Version 2 as
#  published by the Free Software Foundation.
#
#  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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
#  USA.
#
#  $Id: lms-notify,v 1.67 2009/01/13 07:45:28 alec Exp $

use strict;
use DBI;
use Config::IniFiles;
use Getopt::Long;
use vars qw($configfile $my_template $quiet $help $version);
use POSIX qw(strftime);
use MIME::QuotedPrint;
use Mail::Sender;

my $_version = '1.11.7 Bastet';

my %options = (
	"--config-file|C=s"	=>	\$configfile,
	"--template-file|D=s"	=> 	\$my_template,
	"--quiet|q"		=>	\$quiet,
	"--help|h"		=>	\$help,
	"--version|v"		=>	\$version
);

Getopt::Long::config("no_ignore_case");
GetOptions(%options);

if($help)
{
	print STDERR <<EOF;
lms-notify, version $_version
(C) 2001-2009 LMS Developers

-C, --config-file=/etc/lms/lms.ini	alternate config file (default: /etc/lms/lms.ini);
-D, --template-file=/etc/lms/other.template.txt	alternate file with message template;
-h, --help			print this help and exit;
-v, --version			print version info and exit;
-q, --quiet			suppress any output, except errors;

EOF
	exit 0;
}

if($version)
{
	print STDERR <<EOF;
lms-notify, version $_version
(C) 2001-2009 LMS Developers

EOF
	exit 0;
}

if(!$configfile)
{
	$configfile = "/etc/lms/lms.ini";
}

if(!$quiet)
{
	print STDOUT "lms-notify, version $_version\n";
	print STDOUT "(C) 2001-2009 LMS Developers\n";
	print STDOUT "Using file $configfile as config.\n";
}

if(! -r $configfile)
{
	print STDERR "Fatal error: Unable to read configuration file $configfile, exiting.\n";
	exit 1;
}

my $ini = new Config::IniFiles -file => $configfile;
print @Config::IniFiles::errors;

my $dbtype = $ini->val('database', 'type') || 'mysql';
my $dbhost = $ini->val('database', 'host') || 'localhost';
my $dbuser = $ini->val('database', 'user') || 'root';
my $dbpasswd = $ini->val('database', 'password') || '';
my $dbname = $ini->val('database', 'database') || 'lms';

my $smtp_host = $ini->val('sendinvoices', 'smtp_host') || 'localhost';
my $smtp_user = $ini->val('sendinvoices', 'smtp_user') || '';
my $smtp_pass = $ini->val('sendinvoices', 'smtp_pass') || '';
my $smtp_auth = $ini->val('sendinvoices', 'smtp_auth') || ''; # 'LOGIN', 'PLAIN', 'CRAM-MD5', 'NTLM'

my $limit = $ini->val('notify', 'limit') || 0;
my $mtfile = $my_template || $ini->val('notify', 'mailtemplate');
my $mailfrom = $ini->val('notify', 'mailfrom') || '';
my $mailfname = $ini->val('notify', 'mailfname') || '';
my $mailsubject = $ini->val('notify', 'mailsubject') || '';
my $debugemail = $ini->val('notify', 'debug_email') || '';

if(!$mtfile)
{
	print STDERR "Fatal error: mailtemplate in $configfile unset! Can't continue, exiting.\n";
	exit 1;
}

if(! -r $mtfile)
{
	print STDERR "Fatal error: unable to read mail template file $mtfile, exiting!\n";
	exit 1;
}

if(!$mailfrom)
{
	print STDERR "Fatal error: mailfrom unset! Can't continue, exiting.\n";
	exit 1;
}

if(!$mailsubject)
{
	print STDERR "Fatal error: mailsubject unset! Can't continue, exiting.\n";
	exit 1;
}

if($smtp_auth && $smtp_auth !~ /LOGIN|PLAIN|CRAM-MD5|NTLM/i)
{
        print STDERR "Fatal error: smtp_auth setting not supported! Can't continue, exiting.\n";
        exit 1;
}

my $dbase;
my $utsfmt;

if($dbtype =~ /mysql/)
{
	$dbase = DBI->connect("DBI:mysql:database=$dbname;host=$dbhost","$dbuser","$dbpasswd", { RaiseError => 1 });
	$dbase->do("SET NAMES utf8");
	$utsfmt = "UNIX_TIMESTAMP()";
}
elsif($dbtype eq "postgres")
{
	$dbase = DBI->connect("DBI:Pg:dbname=$dbname;host=$dbhost","$dbuser","$dbpasswd", { RaiseError => 1 });
	$utsfmt = "EXTRACT(EPOCH FROM CURRENT_TIMESTAMP(0))";
}
else
{
	print STDERR "Fatal error: unsupported database type: $dbtype, exiting.\n";
	exit 1;
}

my $from = $mailfrom;

if($mailfname)
{
        $mailfname = '=?UTF-8?Q?'.encode_qp($mailfname, '').'?=';
	$from = '"'.$mailfname.'"'.' <'.$from.'>';
}

open(MTFILE, "$mtfile");
my @mtempl = <MTFILE>;
close MTFILE;

$Mail::Sender::NO_X_MAILER = 1;
$Mail::Sender::SITE_HEADERS = "X-Mailer: lms-notify v.$_version";

my $dbq = $dbase->prepare("SELECT customers.id AS id, pin, UPPER(lastname) AS lastname, 
		name, email, SUM(cash.value) AS balance 
		FROM customers 
		JOIN cash ON (customers.id = cash.customerid)
		WHERE deleted = 0 AND email != ''
		GROUP BY customers.id, pin, lastname, name, email 
		HAVING SUM(cash.value) < $limit");
$dbq->execute();
while (my $row = $dbq->fetchrow_hashref())
{
	my $balance = $row->{'balance'};
	my $recipient = $debugemail || $row->{'email'};

	if(!$quiet)
	{
		print STDOUT "$row->{'lastname'} $row->{'name'} (".sprintf("%04d",$row->{'id'}).")\t$balance\n";
	}

	if(!$quiet)
	{
		print STDOUT "Sending e-mail to <$recipient>\n";
	}
		
	my @desttempl = @mtempl;
	my $subject = $mailsubject;
	my $body = '';
	my $sender;
		
	$subject =~ s/\%B/$balance/g;

	{
		my $amount = -$balance; $subject =~ s/\%b/$amount/g;
	} 
		
	foreach my $line (@desttempl)
	{
		{ 	
			my $amount = sprintf "%.2f", -$balance;
			$line =~ s/\%b/$amount/g; 	
		}
		{ 
			my $year = strftime( "%Y", localtime());
			$line =~ s/\%date-y/$year/; 
		}
		{
			my $month = strftime ( "%m", localtime());
			$line =~ s/\%date-m/$month/;
		}
		{
			my $month_name = strftime ( "%B", localtime());
			$line =~ s/\%date_month_name/$month_name/;
		}
			
		$line =~ s/\%B/$balance/g;
		$line =~ s/\%saldo/$row->{'balance'}/;
		$line =~ s/\%pin/$row->{'pin'}/;
		$line =~ s/\%cid/$row->{'id'}/;

		if ($line =~ /\%abonament/) {
			my $saldo_dbq = $dbase->prepare("SELECT sum(value) AS value FROM assignments, tariffs 
					WHERE tariffid = tariffs.id AND (datefrom <= $utsfmt OR datefrom = 0) 
						AND (dateto > $utsfmt OR dateto = 0) 
						AND ((datefrom < dateto) OR (datefrom = 0 AND datefrom = 0)) 
						AND customerid = $row->{'id'}");
			$saldo_dbq->execute();
			my $ow_s = $saldo_dbq->fetchrow_hashref();
			$saldo_dbq->finish();
			$line =~ s/\%abonament/$ow_s->{'value'}/;
		}
		if ($line =~ /\%last_10_in_a_table/ ) {
			my $last10_dbq = $dbase->prepare("SELECT comment, value, time FROM cash WHERE 
					customerid='$row->{'id'}' ORDER BY time DESC LIMIT 10");
			# ok, now we are going to rise up system's load
			$last10_dbq->execute();
			my $l10 = "-----------+-----------+----------------------------------------------------\n";
			while (my $row_s = $last10_dbq->fetchrow_hashref())
			{
				my $op_time = strftime( "%Y/%m/%d", localtime($row_s->{'time'}));
				my $op_amount = sprintf("%9.2f", $row_s->{'value'});
				my $for_what = sprintf("%-52s",$row_s->{'comment'} || '');
														
				$l10 = $l10."$op_time | $op_amount | $for_what \n";
			}
			$last10_dbq->finish();
			$l10 = $l10."-----------+---------+------------------------------------------------------\n";
			$line =~ s/\%last_10_in_a_table/$l10/;
		} 
		
		$body = $body.$line;
	}
	
	(new Mail::Sender)->MailMsg ({
	        smtp => $smtp_host,
		from => $mailfrom,
		auth => $smtp_auth,
		authid => $smtp_user,
		authpwd => $smtp_pass,
		on_errors => undef,
#		debug_level => 4,
#		debug => './log.txt',
                subject => '=?UTF-8?Q?'.encode_qp($subject, '').'?=',
		fake_from => $from,
		to => $recipient,
		fake_to => '"=?UTF-8?Q?'.encode_qp($row->{'name'}.' '.$row->{'lastname'}, '').'?="'.' <'.$recipient.'>',
		replyto => $mailfrom,
		ctype => 'text/plain',
    		encoding => '8bit',
		charset => 'UTF-8',
		msg => "$body\n",
	}) or print STDERR "Error sending mail: $Mail::Sender::Error\n";
}

$dbq->finish();
$dbase->disconnect();
