From b2c40b58070e939d927f4737c7a1ff5015a1144d Mon Sep 17 00:00:00 2001 From: Roman Dieser Date: Mon, 14 Jan 2013 16:45:05 +0000 Subject: [PATCH] first version of the daily limit check --- bin/ngcp-fraud-daily-lock | 102 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100755 bin/ngcp-fraud-daily-lock diff --git a/bin/ngcp-fraud-daily-lock b/bin/ngcp-fraud-daily-lock new file mode 100755 index 0000000..adbb186 --- /dev/null +++ b/bin/ngcp-fraud-daily-lock @@ -0,0 +1,102 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Email::Sender::Simple qw(sendmail); +use Sipwise::Provisioning::Billing; + +my %LOCK = ( + none => undef, + foreign => 1, + outgoing => 2, + incoming => 3, + global => 4, + 0 => 'none', + 1 => 'foreign', + 2 => 'outgoing', + 3 => 'incoming', + 4 => 'global', +); + +my $conf = Sipwise::Provisioning::Config->new()->get_config(); + +my $o = Sipwise::Provisioning::Billing->new(); +my $db = $o->{database}; + +my $a = $db->sql_get_all_arrayref(<<"!"); +SELECT cdr.source_account_id, SUM(cdr.customer_cost) AS daily_cost, + contracts.id, + billing_mappings.billing_profile_id, billing_mappings.start_date, billing_mappings.end_date, + billing_profiles.fraud_daily_limit, billing_profiles.fraud_daily_lock, billing_profiles.fraud_daily_notify +FROM accounting.cdr +JOIN billing.contracts ON cdr.source_account_id = contracts.id +JOIN billing.billing_mappings ON contracts.id = billing_mappings.contract_id +JOIN billing.billing_profiles + ON (billing_profiles.id = + (SELECT m.billing_profile_id + FROM billing.billing_mappings m + WHERE ((m.start_date IS NULL) OR (m.start_date <= NOW())) + AND ((m.end_date IS NULL) OR (m.end_date >= NOW())) + AND (m.contract_id = contracts.id) + ORDER BY m.start_date DESC LIMIT 1 + ) + ) +WHERE (contracts.status = 'active') + AND (DATEDIFF(FROM_UNIXTIME(cdr.start_time), CURDATE()) = 0) + AND (billing_profiles.fraud_daily_limit IS NOT NULL) +GROUP BY cdr.source_account_id +HAVING (daily_cost > billing_profiles.fraud_daily_limit) +! + +for my $e (@$a) { + $e->{fraud_daily_lock} and + $o->lock_voip_account({id => $e->{id}, lock => $LOCK{$e->{fraud_daily_lock}}}); + + $e->{fraud_daily_notify} or next; + + my $subs = $db->sql_get_all_arrayref(<<"!", $e->{id}); + SELECT s.username, d.domain, s.external_id + FROM voip_subscribers s + LEFT JOIN domains d ON d.id = s.domain_id + WHERE s.contract_id = ? +! + + my $cur = sprintf('%.2f', $e->{daily_cost} / 100); + my $max = sprintf('%.2f', $e->{fraud_daily_limit} / 100); + + my ($subject, $body); + if ($e->{fraud_daily_lock}) { + $body = "Account ID " . $e->{id} . " has been locked due to exceeding the configured" . "\n" + . "credit daily balance threshold ($cur >= $max ).\n\n"; + $subject = 'Account ID ' . $e->{id} . ' locked by fraud detection'; + } + else { + $body = "Account ID " . $e->{id} . " is currently exceeding the configured credit daily balance" . "\n" + . "threshold ($cur >= $max), but has not been locked due to configuration.\n\n"; + $subject = 'Account ID ' . $e->{id} . ' exceeding fraud detection limit'; + } + + if (!$subs || !@$subs) { + $body .= "There are no affected subscribers.\n"; + } + else { + $body .= "Affected subscribers:\n"; + for my $s (@$subs) { + $body .= "\t$s->{username}\@$s->{domain}". + ($s->{external_id} ? " (external ID '$s->{external_id}')" + : '') . "\n"; + } + } + + sendmail ( Email::Simple->create( + header => [ + To => $e->{fraud_daily_notify}, + From => $$conf{adminmail}, + Subject => $subject, + ], + body => $body, + )); +} + +1;