#!/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-sms,v 1.37 2009/01/13 07:45:28 alec Exp $

use strict;
use DBI;
use Config::IniFiles;
use Getopt::Long;
use vars qw($configfile $quiet $help $version $debug);
use POSIX qw(strftime);

$ENV{'PATH'}='/sbin:/usr/sbin:/usr/local/sbin:/bin:/usr/bin:/usr/local/bin';

my $_version = '1.11.7 Bastet';
my $my_template;

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

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

if($help)
{
	print STDERR <<EOF;
lms-notify-sms, 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/smstemplate.txt	alternate (default in confing file);
-h, --help			print this help and exit;
-v, --version			print version info and exit;
-q, --quiet			suppress any output, except errors;
-d, --debug			do debugging, don't send anything.

EOF
	exit 0;
}

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

EOF
	exit 0;
}

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

if(!$quiet)
{
	print STDOUT "lms-notify-sms, version $_version\n";
	print STDOUT "(C) Copyright 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 $limit = $ini->val('notify-sms', 'limit') || 0;
my $smsfile = $my_template || $ini->val('notify-sms', 'smstemplate');

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

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

my $dbase;
my $utsfmt;
my $regexp;

if($dbtype =~ /mysql/)
{
	$dbase = DBI->connect("DBI:mysql:database=$dbname;host=$dbhost","$dbuser","$dbpasswd", { RaiseError => 1 });
	$dbase->do("SET NAMES utf8");
	$utsfmt = "UNIX_TIMESTAMP()";
	
	# for Poland:
	# 888xxxxxx 880xxxxxx (heyah), 6(0,9)xxxxxxx (plus and era), 50xxxxxxx (idea)
	# it will also treat as valid numbers begining with: +48, 0, 0-, 0 (space)...

	$regexp = "phone REGEXP '^(\\\\+48|0)?(88[08]|50[0-9]|6[09][0-9])[0-9]{6}\$'";
}
elsif($dbtype eq "postgres")
{
	$dbase = DBI->connect("DBI:Pg:dbname=$dbname;host=$dbhost","$dbuser","$dbpasswd", { RaiseError => 1 });
	$utsfmt = "EXTRACT(EPOCH FROM CURRENT_TIMESTAMP(0))";
	$regexp = "regexp_replace(phone, '[^0-9]', '') ~ '^(48|0|)(88[08]|50[0-9]|6[09][0-9])[0-9]{6}$'";
}
else
{
	print STDERR "Fatal error: unsupported database type: $dbtype, exiting.\n";
	exit 1;
}

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

my $dbq = $dbase->prepare("SELECT customers.id AS id, pin, lastname, name, SUM(value) AS balance,
			(SELECT phone FROM customercontacts c 
				WHERE c.customerid = customers.id AND $regexp
				LIMIT 1
			) AS phone
		FROM customers 
		LEFT JOIN cash ON (customers.id = cash.customerid)
		GROUP BY customers.id, pin, lastname, name
		HAVING SUM(value) < 0"); 
$dbq->execute();
while (my $row = $dbq->fetchrow_hashref())
{
	my $balance = $row->{'balance'};
	if($balance < $limit)
	{
		if(!$quiet)
		{
			print STDOUT "$row->{'id'}\t($balance)\t$row->{'lastname'} $row->{'name'}\n";
		}
		
		$row->{'phone'} =~ s/[^0-9]//g;
			
		if($row->{'phone'})
		{
			if(!$quiet)
			{
				print STDOUT "Sending sms to $row->{'phone'}\n";
			}
			
			my @desttempl = @mtempl;
			
			my $sms_data = "";

			foreach my $line (@desttempl)
			{
				$line =~ s/\%B/$balance/g;
				{ 	
					my $amount = -$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/;
				}

				if ($line =~ /\%saldo/) {
					$line =~ s/\%saldo/$balance/;
				}

				if ($line =~ /\%pin/) {
					$line =~ s/\%pin/$row->{'pin'}/;
				}

				if ($line =~ /\%cid/) {
					$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();
					$line =~ s/\%abonament/$ow_s->{'value'}/;
				}
			
				$sms_data .= $line;
			}
			
			if(!$debug) 
			{
				system("echo $sms_data | gnokii --sendsms $row->{'phone'}");
			}
		}
		elsif(!$quiet) 
		{
				print STDOUT "This customer don't have any sms capable number in database.\n";
		}
	}
}

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