Выкладываю перловый скрипт для округления трафика, может кому и пригодится:
Код:
#!/usr/bin/perl -w
##################################################################
# Скрипт округления трафика за предыдущий месяц в БД BGBilling #
##################################################################
=for
Год и месяц задаются в командной строке, например:
# bg-round.pl 2009 7
Для передачи в скрипт текущей даты можно использовать команду date:
# bg-round.pl `date "+%Y"` `date "+%m"`
Для запуска из-под cron'а не забываем escape'ить символ "%":
20 0 1 * * bg-round.pl `date "+\%Y"` `date "+\%m"`
После выполнения скрипта необходимо запустить переначисление трафиков
в клиенте BGBilling
=cut
use strict;
use DBI;
my $mid = 2; # Код модуля IPN
my $mb_bytes = 1048576; # Байт в мегабайте
# Конфигурация БД
my %c = (
host => 'localhost',
user => 'user',
pass => 'pass',
db => 'bgbilling'
);
# Дата принимается из командной строки ...
my $year = $ARGV[0] ? $ARGV[0] : "2009";
my $month = $ARGV[1] ? $ARGV[1] : "7";
# ... и берется предыдущий месяц
if ($month == 1) {
$year -= 1;
$month = 12;
} else {
$month -= 1;
}
my $yyyymm = $year.sprintf("%02d", $month); # Нужный нам период в формате yyyymm
my $ipn_table = "ipn_contract_data_${mid}_${yyyymm}"; # Таблица с данными по трафику
my $dsn = join ';',
"DBI:mysql:database=$c{'db'};host=$c{'host'}",
'mysql_read_default_group=client',
'mysql_read_default_file=/etc/my.cnf';
my $dbh = DBI->connect($dsn, $c{'user'}, $c{'pass'}, {RaiseError => 1, AutoCommit => 0}) || die "Can't connect to Mysql: $!";
# Выберем все договора, к которым привязан модуль IPN
my $sql = "select cid, title, comment from contract c join contract_module cm on c.id=cm.cid where mid=$mid group by cid, title, comment";
my $sth = $dbh->prepare($sql);
my $rc = $sth->execute;
my $ref = $sth->fetchall_arrayref;
# Заголовок отчета
print " cid | customer | sid | summa | rounded | delta | max_id \n";
print "------------------------------------------------------------------------------------------------\n";
# Цикл по договорам
foreach my $r (@$ref) {
# cid - номер (идентификатор) договора, customer - комментарий к договору (название клиента)
my $cid = $r->[0];
my $customer = $r->[2];
$sql = "select sid, sum(amount)/$mb_bytes summa from $ipn_table where cid=$cid group by sid";
$sth = $dbh->prepare($sql);
$rc = $sth->execute;
my $ref1 = $sth->fetchall_arrayref;
# Цикл по услугам (входящий трафик, исходящий и т.д.)
foreach my $r1 (@$ref1) {
# sid - идентификатор услуги, summa - суммарный трафик по услуге в мегабайтах
my $sid = $r1->[0];
my $summa = $r1->[1];
# В delta - разница до округления (в байтах)
my $rounded = sprintf("%.0f", $summa);
my $delta = ($rounded - $summa)*$mb_bytes;
# Выберем последнюю запись в таблице по данному клиенту и данной услуге
$sql = "select max(id) from $ipn_table where cid=$cid and sid=$sid";
$sth = $dbh->prepare($sql);
$sth->execute;
my @arr = $sth->fetchrow_array;
my $max_id = $arr[0];
$sth->finish;
# Изменим количество трафика в этой записи на величину delta
$sql = "update $ipn_table set amount=amount+$delta where id=$max_id";
$sth = $dbh->do($sql);
# Выведем данные в отчет
printf "%4s |%34s |%4s |%12.2f |%12d |%8d |%8d\n", $cid, $customer, $sid, $summa, $rounded, $delta, $max_id;
}
}
$dbh->disconnect;