[Astpp-commit] SF.net SVN: astpp:[2272] trunk/modules/ASTPP/lib/ASTPP.pm
Brought to you by:
darrenkw
From: <dar...@us...> - 2009-10-03 04:40:57
|
Revision: 2272 http://astpp.svn.sourceforge.net/astpp/?rev=2272&view=rev Author: darrenkw Date: 2009-10-03 04:40:49 +0000 (Sat, 03 Oct 2009) Log Message: ----------- Add a bunch of documentation to our perl module Modified Paths: -------------- trunk/modules/ASTPP/lib/ASTPP.pm Modified: trunk/modules/ASTPP/lib/ASTPP.pm =================================================================== --- trunk/modules/ASTPP/lib/ASTPP.pm 2009-10-02 20:44:18 UTC (rev 2271) +++ trunk/modules/ASTPP/lib/ASTPP.pm 2009-10-03 04:40:49 UTC (rev 2272) @@ -10,7 +10,6 @@ bindtextdomain( "astpp", "/usr/local/share/locale" ); textdomain("astpp"); - require Exporter; our @ISA = qw(Exporter); @@ -19,7 +18,7 @@ # names by default without a very good reason. Use EXPORT_OK instead. # Do not simply export all your public functions/methods/constants. -# This allows declaration use ASTPP ':all'; +# This allows declaration use ASTPP ':all'; # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK # will save memory. our %EXPORT_TAGS = ( 'all' => [ qw( @@ -34,49 +33,116 @@ our $VERSION = '0.01'; + +=head1 NAME + +ASTPP - Perl extension for ASTPP (www.astpp.org). +Module contains functions to assist with the operation of ASTPP (www.astpp.org) + +=head1 EXPORT + +Everything by default. + + +=head1 SYNOPSIS + +use ASTPP; + +$ASTPP = new ASTPP; + +=head1 DESCRIPTION + +This module should make it easier to write scripts that interact with ASTPP + +=head1 MODULE COMMANDS + +=over 4 + +=cut + sub new { my ($class,%arg) = @_; bless { - _astpp_db => $_[1], - _freeswitch_db => $_[1], - _verbosity_level => $arg{verbosity_level} || 1, - _asterisk_agi => $_[3], - _cdr_db => $_[4], - _verbosity_item_level => $arg{verbosity_item_level} || 1, - _script => $arg{script} || "astpp-admin.cgi", - _config => $_[7], + _astpp_db => $_[1], + _freeswitch_db => $_[1], + _verbosity_level => $arg{verbosity_level} || 1, + _asterisk_agi => $_[3], + _cdr_db => $_[4], + _verbosity_item_level => $arg{verbosity_item_level} || 1, + _script => $arg{script} || "astpp-admin.cgi", + _config => $_[7], }, $class; } -sub set_verbosity_level { $_[0]->{_verbosity_level} } #Sets the verbosity level. -sub set_verbosity { $_[0]->{_verbosity_level} } #Sets the verbosity level. One of these needs to be deprecated. +sub set_verbosity_level { $_[0]->{_verbosity_level} } #Sets the verbosity level. +sub set_verbosity { $_[0]->{_verbosity_level} } #Sets the verbosity level. One of these needs to be deprecated. +=item $ASTPP->set_astpp_db() + +Pushes the ASTPP database connection into module for internal use + +Example: $ASTPP->set_astpp_db($astpp_db) + +=cut + sub set_astpp_db { my ($self, $astpp_db) = @_; $self->{_astpp_db} = $astpp_db if $astpp_db; } +=item $ASTPP->set_freeswitch_db() + +Pushes the Freeswitch database connection into module for internal use + +Example: $ASTPP->set_freeswitch_db($freeswitch_db) + +=cut + sub set_freeswitch_db { my ($self, $freeswitch_db) = @_; $self->{_freeswitch_db} = $freeswitch_db if $freeswitch_db; } +=item $ASTPP->set_cdr_db() + +Pushes the cdr database connection into module for internal use + +Example: $ASTPP->set_cdr_db($cdr_db) + +=cut + sub set_cdr_db { my ($self, $cdr_db) = @_; $self->{_cdr_db} = $cdr_db if $cdr_db; } +=item $ASTPP->set_asterisk_agi() + +Pushes the Asterisk AGI connection into module for internal use + +Example: $ASTPP->set_asterisk_agi($AGI) + +=cut + sub set_asterisk_agi { my ($self, $asterisk_agi) = @_; $self->{_asterisk_agi} = $asterisk_agi if $asterisk_agi; } -sub set_pagination_script #Set the location of the script we are working in. +=item $ASTPP->set_pagination_script() + +Set the location of the script we are working in so that we return the correct url + +Example: $ASTPP->set_pagination_script("astpp-admin.cgi") + +=cut + +sub set_pagination_script { my ($self, $script) = @_; $self->{_script} = $script if $script; @@ -84,62 +150,95 @@ #sub set_config #{ -# my ($self, %config_hash) = @_; -# $self->{_config} = %config_hash if %config_hash; +# my ($self, %config_hash) = @_; +# $self->{_config} = %config_hash if %config_hash; #} +=item $ASTPP->load_config() + +Read the ASTPP configuration file and return it as a hash + +Example: $config = $ASTPP->load_config() + +=cut + sub load_config { my ($self, %arg) = @_; my $config; open( CONFIG, "</var/lib/astpp/astpp-config.conf" ); while (<CONFIG>) { - chomp; # no newline - s/#.*//; # no comments - s/^\s+//; # no leading white - s/\s+$//; # no trailing white - next unless length; # anything left? - my ( $var, $value ) = split( /\s*=\s*/, $_, 2 ); - $config->{$var} = $value; + chomp; # no newline + s/#.*//; # no comments + s/^\s+//; # no leading white + s/\s+$//; # no trailing white + next unless length; # anything left? + my ( $var, $value ) = split( /\s*=\s*/, $_, 2 ); + $config->{$var} = $value; } close(CONFIG); return $config; } +=item $ASTPP->connect_db() + +Connect to a database and return the connection. This can be used for either +Postgresql on MySQL. + +Example: +$astpp_db = $ASTPP->connect_db( + dbengine => "MySQL", + dbname => "astpp", + dbhost => "localhost", + dbuser => "root", + dbpass => "Passw0rd!" +) + +=cut + sub connect_db { my ($self, %arg) = @_; my ( $dbh, $dsn ); if ( $arg{dbengine} eq "MySQL" ) { - $dsn = "DBI:mysql:database=$arg{dbname};host=$arg{dbhost}"; + $dsn = "DBI:mysql:database=$arg{dbname};host=$arg{dbhost}"; } elsif ( $arg{dbengine} eq "Pgsql" ) { - $dsn = "DBI:Pg:database=$arg{dbname};host=$arg{dbhost}"; + $dsn = "DBI:Pg:database=$arg{dbname};host=$arg{dbhost}"; } $dbh = DBI->connect( $dsn, $arg{dbuser}, $arg{dbpass} ); if ( !$dbh ) { - print STDERR "ASTPP DATABASE IS DOWN\n"; - return 0; + print STDERR "DATABASE: " . $arg{dbname} . " IS DOWN\n"; + return 0; } else { - $dbh->{mysql_auto_reconnect} = 1; - print STDERR gettext("Connected to ASTPP Database!") . "\n"; - return $dbh; + $dbh->{mysql_auto_reconnect} = 1; + print STDERR "Connected to " . $arg{dbname} . " Database!" . "\n"; + return $dbh; } } +=item $ASTPP->ip_address_authenticate() -sub ip_address_authenticate #Authenticates call by caller ip address. Works with both Asterisk(tm) and Freeswitch(tm) -# Requires -# ip_address = IP Address of calling device -# destination = Dialed number +Authenticates call by caller ip address. Works with both Asterisk(tm) and +Freeswitch(tm). + +Example: +$ipdata = $ASTPP->ip_address_authenticate( + ip_address => "192.168.1.1", + destination => "18005551212" +) + +=cut + +sub ip_address_authenticate { my ($self, %arg) = @_; - my ($sql,$tmp); + my ($sql,$tmp); $arg{ip_address} = $arg{ip} if $arg{ip}; #Freeswitch passes the ip in a different format. $tmp = "SELECT * FROM ip_map WHERE ip = " . $self->{_astpp_db}->quote($arg{ip_address}) . " AND prefix IN (NULL,'') OR ip = " . $self->{_astpp_db}->quote($arg{ip_address}); - $tmp .= " AND " . $self->{_astpp_db}->quote($arg{destination}) . " RLIKE prefix" if $arg{destination}; + $tmp .= " AND " . $self->{_astpp_db}->quote($arg{destination}) . " RLIKE prefix" if $arg{destination}; $tmp .= " ORDER BY LENGTH(prefix) DESC LIMIT 1"; print STDERR $tmp; $sql = $self->{_astpp_db}->prepare($tmp); @@ -149,8 +248,22 @@ return $anidata; } +=item $ASTPP->fs_dialplan_xml_header() + +Return the opening lines of the Freeswitch(TM) xml dialplan. If a call is +inbound via a DID or if we're authenticating via IP address we need to be in the +public context instead of the default context. + +Example: +$xml .= $ASTPP->fs_dialplan_xml_header( + DID => $diddata->{number}, + IP => $ipdata->{account}, + destination_number => $dialed_number +) + +=cut + sub fs_dialplan_xml_header -#Return the opening lines of the Freeswitch(TM) xml dialplan { my ($self, %arg) = @_; $arg{xml} .= "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"; @@ -168,24 +281,45 @@ return $arg{xml}; } -sub fs_dialplan_xml_timelimit -#Return the opening lines of the Freeswitch(TM) xml dialplan -{ +=item $ASTPP->fs_dialplan_xml_timelimit() + +Return lines of the Freeswitch(TM) xml dialplan that set the accountcode as well +as limit the length of the call. + +Example: +$xml .= $ASTPP->fs_dialplan_xml_timelimit( + accountcode => $carddata->{number}, + max_length => $maxlength +) + +=cut + +sub fs_dialplan_xml_timelimit() { my ($self, %arg) = @_; $arg{xml} .= "<action application=\"sched_hangup\" data=\"+" . $arg{max_length} * 60 . "\"/>\n"; $arg{xml} .= "<action application=\"set\" data=\"accountcode=" . $arg{accountcode} . "\"/>\n"; return $arg{xml}; } -sub fs_dialplan_xml_did -# Return the dialplan code for an incoming call to a DID. -{ +=item $ASTPP->fs_dialplan_xml_did() + +Return the dialplan code for an incoming call to a DID. + +Example: +$xml .= $ASTPP->fs_dialplan_xml_did( + did => $destination, + accountcode => $carddata->{number} +) + +=cut + +sub fs_dialplan_xml_did() { my ($self, %arg) = @_; my ( $xml,$sql, $trunkdata, $dialstring,$data ); my $tmp = "SELECT * FROM dids WHERE number = " . $self->{_astpp_db}->quote( $arg{did} ) . " LIMIT 1"; - print STDERR $tmp; + print STDERR $tmp; $sql = $self->{_astpp_db}->prepare($tmp); $sql->execute; my $diddata = $sql->fetchrow_hashref; @@ -205,16 +339,24 @@ $xml .= "<action application=\"bridge\" data=\"" . $diddata->{extensions} . "\"/>\n"; } - return $xml; + return $xml; } -sub fs_dialplan_xml_bridge -#Return the bridge command along with details. This is only called if a call is approved. -# Requires the following variables: -# destination_number = The number we are trying to call -# trunk_name = The name of the trunk we're using. -# route_prepend = What do we tag on for numbers on this route? -{ + +=item $ASTPP->fs_dialplan_xml_bridge() + +Return the bridge command along with details. This is only called if a call is approved. + +Example: +$xml .= $ASTPP->fs_dialplan_xml_bridge( + destination_number => $destination, + trunk_name => $route->{trunk}, + route_prepend => $route->{prepend} +) + +=cut + +sub fs_dialplan_xml_bridge() { my ($self, %arg) = @_; my ( $sql, $trunkdata, $dialstring,$data ); $sql = $self->{_astpp_db}->prepare( "SELECT * FROM trunks WHERE name = " @@ -240,7 +382,7 @@ } if ( $trunkdata->{tech} eq "Zap" ) { $dialstring .= "<action application=\"bridge\" data=\"openzap/" . $trunkdata->{path} . "/1/" . $arg{route_prepend} . $arg{destination_number} . "\"/>\n"; - return ($dialstring,$data); + return ($dialstring,$data); } elsif ( $trunkdata->{tech} eq "SIP" ) { my ($profile,$dest) = split(m/","/m, $trunkdata->{path}); @@ -253,17 +395,23 @@ $data = "sofia/" . $profile . "/" . $arg{route_prepend} . $arg{destination_number} . "\@" . $dest; $dialstring .= "<action application=\"bridge\" data=\"" . $data . "\"/>\n"; } - return ($dialstring,$data); + return ($dialstring,$data); } else { print STDERR "CANNOT ROUTE THIS CALL!!!!!\n"; - return ""; + return ""; } } -sub fs_dialplan_xml_footer -#Return the closing lines of the Freeswitch(TM) xml dialplan -{ +=item $ASTPP->fs_dialplan_xml_footer() + +Return the closing lines of the Freeswitch(TM) xml dialplan + +Example: $xml .= $ASTPP->fs_dialplan_xml_footer(); + +=cut + +sub fs_dialplan_xml_footer() { my ($self, %arg) = @_; $arg{xml} .= "</condition>\n"; $arg{xml} .= "</extension>\n"; @@ -273,11 +421,17 @@ return $arg{xml}; } -sub fs_directory_xml_header -#Return the opening lines of the Freeswitch(TM) xml directory -#xml = Current XML code, usually blank. -#domain = domain name -{ +=item $ASTPP->fs_directory_xml_header() + +Return the opening lines of the Freeswitch(TM) xml directory. + +Example: $xml .= $ASTPP->fs_directory_xml_header( + xml => "" +); + +=cut + +sub fs_directory_xml_header() { my ($self, %arg) = @_; $arg{xml} .= "<?xml version=\"1.0\"?>\n"; $arg{xml} .= "<document type=\"freeswitch/xml\">\n"; @@ -285,198 +439,224 @@ return $arg{xml}; } -sub fs_add_sip_user -# Add a SIP user -# Arguments -# sip_ext_prepend = $config->{sip_ext_prepend} -# accountcode -# context = $config->{freeswitch_context} -# vm_password = Password -# password = Password -# -{ +=item $ASTPP->fs_directory_xml_header() + +Add a SIP user to the Freeswitch database. The "username" parameter is optional. +if it is not passed then we generate a random one using "accountcode" as a base. + +Example: + +($status_code,$status_text) = $ASTPP->fs_add_sip_user( + sip_ext_prepend => $config->{sip_ext_prepend} + accountcode => $params->{accountcode}, + context => $config->{freeswitch_context}, + vm_password => $params->{vmpassword}, + password => $params->{password}, + username => $params->{username} +); + +=cut + +sub fs_add_sip_user() { my ($self, %arg) = @_; # Find uniqueid to prepend to the login my $sipid = 0; if (!$arg{username} || $arg{username} eq "") { $arg{username} = $arg{accountcode}; for ( ; ; ) { - my $count = 1; - $sipid = - int( rand() * 9000 + 1000 ) - . int( rand() * 9000 + 1000 ) - . int( rand() * 9000 + 1000 ) - . int( rand() * 9000 + 1000 ) - . int( rand() * 9000 + 1000 ) - . int( rand() * 9000 + 1000 ) - . int( rand() * 9000 + 1000 ) - . int( rand() * 9000 + 1000 ); - $sipid = $arg{sip_ext_prepend} . $sipid; - $sipid = substr( $sipid, 0, 5 ); - $sipid = $arg{username} . $sipid; - my $sql = - $self->{_freeswitch_db}->prepare( - "SELECT COUNT(*) FROM directory WHERE username = " - . $self->{_freeswitch_db}->quote($sipid) ); - $sql->execute; - my $record = $sql->fetchrow_hashref; - $sql->finish; - if ( $record->{"COUNT(*)"} == 0 ) { + my $count = 1; + $sipid = + int( rand() * 9000 + 1000 ) + . int( rand() * 9000 + 1000 ) + . int( rand() * 9000 + 1000 ) + . int( rand() * 9000 + 1000 ) + . int( rand() * 9000 + 1000 ) + . int( rand() * 9000 + 1000 ) + . int( rand() * 9000 + 1000 ) + . int( rand() * 9000 + 1000 ); + $sipid = $arg{sip_ext_prepend} . $sipid; + $sipid = substr( $sipid, 0, 5 ); + $sipid = $arg{username} . $sipid; + my $sql = + $self->{_freeswitch_db}->prepare( + "SELECT COUNT(*) FROM directory WHERE username = " + . $self->{_freeswitch_db}->quote($sipid) ); + $sql->execute; + my $record = $sql->fetchrow_hashref; + $sql->finish; + if ( $record->{"COUNT(*)"} == 0 ) { last; } } } else { - $arg{username} =~ s/\W//mg; + $arg{username} =~ s/\W//mg; $sipid = $arg{username} } my $tmp = - "INSERT INTO directory (username,domain) VALUES (" + "INSERT INTO directory (username,domain) VALUES (" . $self->{_freeswitch_db}->quote($sipid) . ", " . $self->{_freeswitch_db}->quote($arg{freeswitch_domain}). ")"; print STDERR $tmp . "\n"; my $sql = $self->{_freeswitch_db}->prepare($tmp); if ( !$sql->execute ) { - print "$tmp failed"; - return (1,"SIP Device Creation Failed!"); + print "$tmp failed"; + return (1,"SIP Device Creation Failed!"); } else { - my $directory_id = $sql->{'mysql_insertid'}; - my $tmp = "INSERT INTO directory_vars (directory_id,var_name,var_value) VALUES (" - . $self->{_freeswitch_db}->quote($directory_id) . "," - . "'accountcode'," - . $self->{_freeswitch_db}->quote($arg{accountcode}) + my $directory_id = $sql->{'mysql_insertid'}; + my $tmp = "INSERT INTO directory_vars (directory_id,var_name,var_value) VALUES (" + . $self->{_freeswitch_db}->quote($directory_id) . "," + . "'accountcode'," + . $self->{_freeswitch_db}->quote($arg{accountcode}) . "),(" - . $self->{_freeswitch_db}->quote($directory_id) . "," - . "'user_context'," - . $self->{_freeswitch_db}->quote($arg{freeswitch_context}) . ")"; + . $self->{_freeswitch_db}->quote($directory_id) . "," + . "'user_context'," + . $self->{_freeswitch_db}->quote($arg{freeswitch_context}) . ")"; print STDERR $tmp . "\n"; - $self->{_freeswitch_db}->do($tmp); + $self->{_freeswitch_db}->do($tmp); - $tmp = "INSERT INTO directory_params (directory_id,param_name,param_value) VALUES (" - . $self->{_freeswitch_db}->quote($directory_id) . "," - . "'vm-password'," - . $self->{_freeswitch_db}->quote($arg{vm_password}) + $tmp = "INSERT INTO directory_params (directory_id,param_name,param_value) VALUES (" + . $self->{_freeswitch_db}->quote($directory_id) . "," + . "'vm-password'," + . $self->{_freeswitch_db}->quote($arg{vm_password}) . "),(" - . $self->{_freeswitch_db}->quote($directory_id) . "," - . "'password'," - . $self->{_freeswitch_db}->quote($arg{password}) . ")"; + . $self->{_freeswitch_db}->quote($directory_id) . "," + . "'password'," + . $self->{_freeswitch_db}->quote($arg{password}) . ")"; print STDERR $tmp . "\n"; - $self->{_freeswitch_db}->do($tmp); + $self->{_freeswitch_db}->do($tmp); - return (0, "SIP Device Added!" . "Username:" . " " . $sipid . " " . "Password:" . " " . $arg{password}, $sipid); + return (0, "SIP Device Added!" . "Username:" . " " . $sipid . " " . "Password:" . " " . $arg{password}, $sipid); } } -sub fs_save_sip_user -{ +sub fs_save_sip_user() { my ($self, %arg) = @_; my $tmp = "UPDATE directory SET username = " - . $self->{_freeswitch_db}->quote($arg{username}) - . " WHERE id = " - . $self->{_freeswitch_db}->quote($arg{directory_id}); + . $self->{_freeswitch_db}->quote($arg{username}) + . " WHERE id = " + . $self->{_freeswitch_db}->quote($arg{directory_id}); print STDERR $tmp . "\n"; $self->{_freeswitch_db}->do($tmp); - $tmp = "UPDATE directory_vars SET var_value = " - . $self->{_freeswitch_db}->quote($arg{accountcode}) + $tmp = "UPDATE directory_vars SET var_value = " + . $self->{_freeswitch_db}->quote($arg{accountcode}) . " WHERE var_name = 'accountcode'" . " AND directory_id = " - . $self->{_freeswitch_db}->quote($arg{directory_id}); + . $self->{_freeswitch_db}->quote($arg{directory_id}); print STDERR $tmp . "\n"; $self->{_freeswitch_db}->do($tmp); $tmp = "UPDATE directory_vars SET var_value = " - . $self->{_freeswitch_db}->quote($arg{freeswitch_context}) + . $self->{_freeswitch_db}->quote($arg{freeswitch_context}) . " WHERE var_name = 'user_context'" . " AND directory_id = " - . $self->{_freeswitch_db}->quote($arg{directory_id}); + . $self->{_freeswitch_db}->quote($arg{directory_id}); print STDERR $tmp . "\n"; $self->{_freeswitch_db}->do($tmp); $tmp = "UPDATE directory_params SET param_value = " - . $self->{_freeswitch_db}->quote($arg{vm_password}) + . $self->{_freeswitch_db}->quote($arg{vm_password}) . " WHERE param_name = 'vm-password'" . " AND directory_id = " - . $self->{_freeswitch_db}->quote($arg{directory_id}); + . $self->{_freeswitch_db}->quote($arg{directory_id}); print STDERR $tmp . "\n"; $self->{_freeswitch_db}->do($tmp); - $tmp = "UPDATE directory_params SET param_value = " - . $self->{_freeswitch_db}->quote($arg{password}) + $tmp = "UPDATE directory_params SET param_value = " + . $self->{_freeswitch_db}->quote($arg{password}) . " WHERE param_name = 'password'" . " AND directory_id = " - . $self->{_freeswitch_db}->quote($arg{directory_id}); + . $self->{_freeswitch_db}->quote($arg{directory_id}); print STDERR $tmp . "\n"; $self->{_freeswitch_db}->do($tmp); - return (0, "SIP Device Saved!" . "Username:" . " " . $arg{username} . " " . "Password:" . " " . $arg{password}, $arg{username}); + return (0, "SIP Device Saved!" . "Username:" . " " . $arg{username} . " " . "Password:" . " " . $arg{password}, $arg{username}); } -sub fs_retrieve_sip_user -# Retrieve a SIP user -# Parameters -# directory_id = directory_id of sip user you are looking for. -{ +=item $ASTPP->fs_retrieve_sip_user() + +Returns the details on the specified Freeswitch SIP user. + +Example: + +$user_data = $ASTPP->fs_retrieve_sip_user( + directory_id => "1" #directory_id of sip user you are looking for. +); + +=cut + +sub fs_retrieve_sip_user() { my ($self, %arg) = @_; - my ($tmp,$record,$sql,$deviceinfo); + my ($tmp,$record,$sql,$deviceinfo); $tmp = "SELECT username FROM directory WHERE id = " - . $self->{_freeswitch_db}->quote($arg{directory_id}); + . $self->{_freeswitch_db}->quote($arg{directory_id}); print STDERR $tmp . "\n"; - $sql = $self->{_freeswitch_db}->prepare($tmp); - $sql->execute; - $record = $sql->fetchrow_hashref; - $sql->finish; + $sql = $self->{_freeswitch_db}->prepare($tmp); + $sql->execute; + $record = $sql->fetchrow_hashref; + $sql->finish; $deviceinfo->{username} = $record->{username}; - $tmp = "SELECT var_value FROM directory_vars WHERE directory_id = " - . $self->{_freeswitch_db}->quote($arg{directory_id}) - . " AND var_name = 'user_context'"; + $tmp = "SELECT var_value FROM directory_vars WHERE directory_id = " + . $self->{_freeswitch_db}->quote($arg{directory_id}) + . " AND var_name = 'user_context'"; print STDERR $tmp . "\n"; - $sql = $self->{_freeswitch_db}->prepare($tmp); - $sql->execute; - $record = $sql->fetchrow_hashref; - $sql->finish; - $deviceinfo->{context} = $record->{var_value}; + $sql = $self->{_freeswitch_db}->prepare($tmp); + $sql->execute; + $record = $sql->fetchrow_hashref; + $sql->finish; + $deviceinfo->{context} = $record->{var_value}; - $tmp = "SELECT param_value FROM directory_params WHERE directory_id = " - . $self->{_freeswitch_db}->quote($arg{directory_id}) - . " AND param_name = 'password' LIMIT 1"; + $tmp = "SELECT param_value FROM directory_params WHERE directory_id = " + . $self->{_freeswitch_db}->quote($arg{directory_id}) + . " AND param_name = 'password' LIMIT 1"; print STDERR $tmp . "\n"; - $sql = $self->{_freeswitch_db}->prepare($tmp); - $sql->execute; - $record = $sql->fetchrow_hashref; - $sql->finish; - $deviceinfo->{password} = $record->{param_value}; + $sql = $self->{_freeswitch_db}->prepare($tmp); + $sql->execute; + $record = $sql->fetchrow_hashref; + $sql->finish; + $deviceinfo->{password} = $record->{param_value}; - $tmp = "SELECT param_value FROM directory_params WHERE directory_id = " - . $self->{_freeswitch_db}->quote($arg{directory_id}) - . " AND param_name = 'vm-password' LIMIT 1"; + $tmp = "SELECT param_value FROM directory_params WHERE directory_id = " + . $self->{_freeswitch_db}->quote($arg{directory_id}) + . " AND param_name = 'vm-password' LIMIT 1"; print STDERR $tmp . "\n"; - $sql = $self->{_freeswitch_db}->prepare($tmp); - $sql->execute; - $record = $sql->fetchrow_hashref; - $sql->finish; - $deviceinfo->{vm_password} = $record->{param_value}; + $sql = $self->{_freeswitch_db}->prepare($tmp); + $sql->execute; + $record = $sql->fetchrow_hashref; + $sql->finish; + $deviceinfo->{vm_password} = $record->{param_value}; - $tmp = "SELECT var_value FROM directory_vars WHERE directory_id = " - . $self->{_freeswitch_db}->quote($arg{directory_id}) - . " AND var_name = 'accountcode' LIMIT 1"; + $tmp = "SELECT var_value FROM directory_vars WHERE directory_id = " + . $self->{_freeswitch_db}->quote($arg{directory_id}) + . " AND var_name = 'accountcode' LIMIT 1"; print STDERR $tmp . "\n"; - $sql = $self->{_freeswitch_db}->prepare($tmp); - $sql->execute; - $record = $sql->fetchrow_hashref; - $sql->finish; - $deviceinfo->{accountcode} = $record->{var_value}; + $sql = $self->{_freeswitch_db}->prepare($tmp); + $sql->execute; + $record = $sql->fetchrow_hashref; + $sql->finish; + $deviceinfo->{accountcode} = $record->{var_value}; return $deviceinfo; } -sub fs_delete_sip_user -#Delete the SIP user -#id = directory.id to delete -{ + +=item $ASTPP->fs_dele_sip_user() + +Delete the specified Freeswitch SIP user. + +Example: + +$status_code = $ASTPP->fs_delete_sip_user( + id => "1" #directory_id of sip user you are deleting. +); + +=cut + +sub fs_delete_sip_user() { my ($self, %arg) = @_; my ($tmp,$sql,@results); $tmp = "DELETE FROM directory WHERE id = " . $self->{_freeswitch_db}->quote($arg{id}); @@ -515,17 +695,17 @@ . $self->{_freeswitch_db}->quote($arg{domain}) . ",'\$\${local_ip_v4}')"; } -# } else { -# if ($arg{domain}) { -# $tmp .= " WHERE domain = " -# . $self->{_freeswitch_db}->quote($arg{domain}); -# } +# } else { +# if ($arg{domain}) { +# $tmp .= " WHERE domain = " +# . $self->{_freeswitch_db}->quote($arg{domain}); +# } } } print STDERR $tmp; - $sql = $self->{_freeswitch_db}->prepare($tmp); - $sql->execute; - while (my $record = $sql->fetchrow_hashref) { + $sql = $self->{_freeswitch_db}->prepare($tmp); + $sql->execute; + while (my $record = $sql->fetchrow_hashref) { print STDERR $record->{username}; push @results, $record; } @@ -540,7 +720,7 @@ my ($tmp,$sql,@results); $tmp = "SELECT * FROM directory_params WHERE directory_id = " . $self->{_freeswitch_db}->quote($id); - $sql = $self->{_freeswitch_db}->prepare($tmp); + $sql = $self->{_freeswitch_db}->prepare($tmp); $sql->execute; while (my $record = $sql->fetchrow_hashref) { push @results, $record; @@ -556,7 +736,7 @@ my ($tmp,$sql,@results); $tmp = "SELECT * FROM directory_vars WHERE directory_id = " . $self->{_freeswitch_db}->quote($id); - $sql = $self->{_freeswitch_db}->prepare($tmp); + $sql = $self->{_freeswitch_db}->prepare($tmp); $sql->execute; while (my $record = $sql->fetchrow_hashref) { push @results, $record; @@ -576,7 +756,7 @@ my ($sql,$sql1,$tmp,$tmp1); $arg{xml} .= "<domain name=\"" . $arg{domain} . "\">"; my @sip_users = &fs_list_sip_usernames($self,%arg); - foreach my $record (@sip_users) { + foreach my $record (@sip_users) { $arg{xml} .= "<user id=\"" . $record->{username} . "\" mailbox=\"" . $record->{mailbox} . "\">\n"; $arg{xml} .= "<params>\n"; my @params = &fs_list_sip_params($self,$record->{id}); @@ -653,8 +833,8 @@ # Therefore we need to pass the Data::Paginate stuff # as well as the total number of pages. # - # mode = What mode do we want. - # sql = SQL to select what we want without the limit commands. + # mode = What mode do we want. + # sql = SQL to select what we want without the limit commands. # # Check to see if there is a parameter called "results_per_page" set. If it's set it overrides our defaults. if (!$arg{results_per_page} || $arg{results_per_page} > 1 ) { @@ -675,14 +855,14 @@ my $te_match = $total_entries ? Digest::MD5::md5_hex("unique_cypher-$total_entries-$arg{sql_check}") : ''; if ( !$total_entries || $verify ne $te_match ) { - # its not ok so re-fetch + # its not ok so re-fetch # $sql = $self->{_astpp_db}->prepare($arg{sql_count}); - $sql = $db->prepare($arg{sql_count}); - $sql->execute; - $record = $sql->fetchrow_hashref; - $total_entries = $record->{"COUNT(*)"}; - $sql->finish; - $te_match = Digest::MD5::md5_hex("unique_cypher-$total_entries-$arg{sql_check}"); + $sql = $db->prepare($arg{sql_count}); + $sql->execute; + $record = $sql->fetchrow_hashref; + $total_entries = $record->{"COUNT(*)"}; + $sql->finish; + $te_match = Digest::MD5::md5_hex("unique_cypher-$total_entries-$arg{sql_check}"); } #if ($te_match <= 0) { $te_match = 0; } @@ -690,44 +870,44 @@ # otherwise its all ok so use it my $pgr = Data::Paginate->new( - { - 'start_array_index_at_zero' => 1, - 'total_entries' => $total_entries, - 'entries_per_page' => $arg{results_per_page}, - 'total_entries_verify_param_value' => $te_match - } + { + 'start_array_index_at_zero' => 1, + 'total_entries' => $total_entries, + 'entries_per_page' => $arg{results_per_page}, + 'total_entries_verify_param_value' => $te_match + } ); # only SELECT current page's records: if ( $total_entries > $pgr->get_entries_on_this_page() ) { - $sql = - $arg{sql_select} . " LIMIT " - . ( $pgr->get_first() - 1 ) . ", " - . $pgr->get_entries_on_this_page(); + $sql = + $arg{sql_select} . " LIMIT " + . ( $pgr->get_first() - 1 ) . ", " + . $pgr->get_entries_on_this_page(); } else { - $sql = $arg{sql_select}; + $sql = $arg{sql_select}; } # First we decide if we have multiple pages... if ($total_entries > 1) { - my $html; - $html = - "<a href=\"" . $self->{_script} . "?mode=" - . $arg{mode} . "&ve=" - . $arg{ve} . "&te=" - . $total_entries - . "&pg=1\">" - . "First Page" - . "</a> | " - . scalar $pgr->get_navi_html() - . "<a href=\"" . $self->{_script} . "?mode=" - . $arg{mode} . "&ve=" - . $arg{ve} . "&te=" - . $total_entries . "&pg=" - . $pgr->get_last_page() . "\">" - . "Last Page" . "</a>"; + my $html; + $html = + "<a href=\"" . $self->{_script} . "?mode=" + . $arg{mode} . "&ve=" + . $arg{ve} . "&te=" + . $total_entries + . "&pg=1\">" + . "First Page" + . "</a> | " + . scalar $pgr->get_navi_html() + . "<a href=\"" . $self->{_script} . "?mode=" + . $arg{mode} . "&ve=" + . $arg{ve} . "&te=" + . $total_entries . "&pg=" + . $pgr->get_last_page() . "\">" + . "Last Page" . "</a>"; return ($sql,$html); } else { @@ -738,16 +918,16 @@ sub list_pricelists { my ($self, %arg) = @_; # Return a list of all pricelists either for the appropriate reseller or without reseller. - my ( $sql, @pricelistlist, $row, $tmp ); - if ( !$arg{reseller} || $arg{reseller} eq "") { - $tmp = + my ( $sql, @pricelistlist, $row, $tmp ); + if ( !$arg{reseller} || $arg{reseller} eq "") { + $tmp = "SELECT name FROM pricelists WHERE status < 2 AND reseller IS NULL ORDER BY name"; } else { - $tmp = - "SELECT name FROM pricelists WHERE status < 2 AND reseller = " - . $self->{_astpp_db}->quote($arg{reseller}) - . " ORDER BY name"; + $tmp = + "SELECT name FROM pricelists WHERE status < 2 AND reseller = " + . $self->{_astpp_db}->quote($arg{reseller}) + . " ORDER BY name"; } $sql = $self->{_astpp_db}->prepare($tmp); $sql->execute; @@ -763,7 +943,7 @@ # Function 2 = return crds # Function 3 = Internal Invoices, Post CDRs. { - my ($self, %arg) = @_; #Count the cdrs billable on a specific account + my ($self, %arg) = @_; #Count the cdrs billable on a specific account my $tmp; if ($arg{function} == 1) { $tmp = "SELECT COUNT(*) FROM cdrs WHERE cardnum = "; @@ -811,9 +991,9 @@ } elsif ($arg{function} == 2) { my @cdrs; - while ( my $record = $sql->fetchrow_hashref ) { - push @cdrs, $record; - } + while ( my $record = $sql->fetchrow_hashref ) { + push @cdrs, $record; + } $sql->finish; return( @cdrs @@ -823,7 +1003,7 @@ sub invoice_list_internal { - my ($self, %arg) = @_; # List Internal Invoices. + my ($self, %arg) = @_; # List Internal Invoices. my ($tmp,$sql,@invoices); $tmp = "SELECT * FROM invoice_list_view"; if ($arg{accountid}) { @@ -841,7 +1021,7 @@ sub invoice_create_internal { - my ($self, %arg) = @_; # Create invoice in ASTPP Internally and return the invoice number. + my ($self, %arg) = @_; # Create invoice in ASTPP Internally and return the invoice number. my $tmp = "INSERT into invoices (accountid,date) VALUES(" . $self->{_astpp_db}->quote($arg{accountid}) . ",curdate())"; @@ -856,7 +1036,7 @@ sub invoice_cdrs_subtotal_internal { - my ($self, %arg) = @_; # Create invoice in ASTPP Internally and return the invoice number. + my ($self, %arg) = @_; # Create invoice in ASTPP Internally and return the invoice number. my ($tmp,$row,$sql,$credit,$debit,$total); $tmp = "SELECT SUM(debit) FROM cdrs WHERE invoiceid = " . $self->{_astpp_db}->quote($arg{invoiceid}); @@ -877,22 +1057,22 @@ $total = ( $debit - $credit ); return ($total/10000); -# $tmp = "INSERT into invoices_total (invoiceid,title,text,value,class,sort_order) VALUES(" -# . $self->{_astpp_db}->quote($arg{invoiceid}) -# . ",'Subtotal',''," -# . $self->{_astpp_db}->quote($total/10000) -# . ",1," -# . $self->{_astpp_db}->quote($arg{sort_order}) -# . ")"; -# $sql = $ $self->{_astpp_db}->prepare($tmp); -# $sql->execute; -# return $arg{sort_order}++; +# $tmp = "INSERT into invoices_total (invoiceid,title,text,value,class,sort_order) VALUES(" +# . $self->{_astpp_db}->quote($arg{invoiceid}) +# . ",'Subtotal',''," +# . $self->{_astpp_db}->quote($total/10000) +# . ",1," +# . $self->{_astpp_db}->quote($arg{sort_order}) +# . ")"; +# $sql = $ $self->{_astpp_db}->prepare($tmp); +# $sql->execute; +# return $arg{sort_order}++; } sub invoice_subtotal_post_internal { my ($self, %arg) = @_; - $arg{value} = sprintf( "%." . $arg{decimalpoints_total} . "f", $arg{value} ); + $arg{value} = sprintf( "%." . $arg{decimalpoints_total} . "f", $arg{value} ); my $tmp = "INSERT into invoices_total (invoices_id,title,text,value,class,sort_order) VALUES(" . $self->{_astpp_db}->quote($arg{invoiceid}) . "," @@ -914,12 +1094,12 @@ sub invoice_subtotal_internal { my ($self, %arg) = @_; - my $tmp = "SELECT SUM(value) FROM invoices_total WHERE invoices_id = " - . $self->{_astpp_db}->quote($arg{invoiceid}); - my $sql = $self->{_astpp_db}->prepare($tmp); - $sql->execute; - my $row = $sql->fetchrow_hashref; - my $value = $row->{"SUM(value)"}; + my $tmp = "SELECT SUM(value) FROM invoices_total WHERE invoices_id = " + . $self->{_astpp_db}->quote($arg{invoiceid}); + my $sql = $self->{_astpp_db}->prepare($tmp); + $sql->execute; + my $row = $sql->fetchrow_hashref; + my $value = $row->{"SUM(value)"}; $sql->finish; return $value; } @@ -928,7 +1108,7 @@ # function 1 = list # function 2 = post { - my ($self, %arg) = @_; # Create invoice in ASTPP Internally and return the invoice number. + my ($self, %arg) = @_; # Create invoice in ASTPP Internally and return the invoice number. my (@taxes,$row,$tmp,$sql); $tmp = "SELECT * FROM taxes_to_accounts_view WHERE accountid = " . $self->{_astpp_db}->quote($arg{accountid}) @@ -947,27 +1127,27 @@ my $sort = 1; my $tax_priority = ""; my $subtotal = $arg{invoice_subtotal}; - foreach my $tax (@taxes) { + foreach my $tax (@taxes) { my ($tax_amount); if ($tax_priority eq "") { $tax_priority = $tax->{taxes_priority}; } elsif($tax->{taxes_priority} > $tax_priority) { $tax_priority = $tax->{taxes_priority}; - my $tmp = "SELECT SUM(value) FROM invoices_total WHERE invoices_id = " - . $self->{_astpp_db}->quote($arg{invoiceid}); + my $tmp = "SELECT SUM(value) FROM invoices_total WHERE invoices_id = " + . $self->{_astpp_db}->quote($arg{invoiceid}); print STDERR $tmp . "\n"; - my $sql = $self->{_astpp_db}->prepare($tmp); - $sql->execute; - my $row = $sql->fetchrow_hashref; - $subtotal = $row->{"SUM(value)"}; + my $sql = $self->{_astpp_db}->prepare($tmp); + $sql->execute; + my $row = $sql->fetchrow_hashref; + $subtotal = $row->{"SUM(value)"}; $sql->finish; } print STDERR "Subtotal: $subtotal \n"; print STDERR "Tax_rate: $tax->{taxes_rate} \n"; - my $tax_total = (($subtotal * ( $tax->{taxes_rate} / 100 )) + $tax->{taxes_amount} ); + my $tax_total = (($subtotal * ( $tax->{taxes_rate} / 100 )) + $tax->{taxes_amount} ); print STDERR "Tax Total: $tax_total \n"; print STDERR "Round to: $arg{decimalpoints_tax} \n"; - $tax_total = sprintf( "%." . $arg{decimalpoints_tax} . "f", $tax_total ); + $tax_total = sprintf( "%." . $arg{decimalpoints_tax} . "f", $tax_total ); print STDERR "Tax Total: $tax_total \n"; my $tmp = "INSERT INTO invoices_total (invoices_id,title,text,value,class,sort_order) VALUES(" . $self->{_astpp_db}->quote($arg{invoiceid}) @@ -982,15 +1162,15 @@ my $sql = $self->{_astpp_db}->prepare($tmp); $sql->execute; - $arg{sort_order}++; - } + $arg{sort_order}++; + } return $arg{sort_order}; } sub account_cdr_post { - my ($self, %arg) = @_; # Create invoice in ASTPP Internally and return the invoice number. + my ($self, %arg) = @_; # Create invoice in ASTPP Internally and return the invoice number. $arg{description} = "" if !$arg{timestamp}; $arg{pricelist} = "" if !$arg{pricelist}; $arg{pattern} = "" if !$arg{pattern}; @@ -1011,50 +1191,62 @@ . $self->{_astpp_db}->quote($arg{pattern}) . ")"; if ( $self->{_astpp_db}->do($tmp) ) { - return (1, "POSTED CDR: $arg{account} in the amount of: " . $arg{amount} / 10000 . "\n"); + return (1, "POSTED CDR: $arg{account} in the amount of: " . $arg{amount} / 10000 . "\n"); } else { - return (2, $tmp . " FAILED! \n"); + return (2, $tmp . " FAILED! \n"); } } -sub get_did -{ - my ($self, %arg) = @_; +=item $ASTPP->get_did() + +Returns the details on the specified DID. + +Example: + +$diddata = $ASTPP->get_did( + reseller => $carddata->{reseller}, + did => $destination +); + +=cut + +sub get_did() { + my ($self, %arg) = @_; my ( $tmp, $sql, $diddata ); if (!$arg{reseller} || $arg{reseller} eq "") { - $tmp = "SELECT * FROM dids WHERE number = " + $tmp = "SELECT * FROM dids WHERE number = " . $self->{_astpp_db}->quote($arg{did}); } else { $tmp = - "SELECT dids.number AS number, " - . "reseller_pricing.monthlycost AS monthlycost, " - . "reseller_pricing.prorate AS prorate, " - . "reseller_pricing.setup AS setup, " - . "reseller_pricing.cost AS cost, " - . "reseller_pricing.connectcost AS connectcost, " - . "reseller_pricing.includedseconds AS includedseconds, " - . "reseller_pricing.inc AS inc, " - . "reseller_pricing.disconnectionfee AS disconnectionfee, " - . "dids.provider AS provider, " - . "dids.country AS country, " - . "dids.city AS city, " - . "dids.province AS province, " - . "dids.extensions AS extensions, " - . "dids.account AS account, " - . "dids.variables AS variables, " - . "dids.options AS options, " - . "dids.maxchannels AS maxchannels, " - . "dids.chargeonallocation AS chargeonallocation, " - . "dids.allocation_bill_status AS allocation_bill_status, " - . "dids.limittime AS limittime, " - . "dids.dial_as AS dial_as, " - . "dids.status AS status " - . "FROM dids, reseller_pricing " - . "WHERE dids.number = " . $self->{_astpp_db}->quote($arg{did}) - . " AND reseller_pricing.type = '1' AND reseller_pricing.reseller = " - . $self->{_astpp_db}->quote($arg{reseller}) . " AND reseller_pricing.note = " - . $self->{_astpp_db}->quote($arg{did}); + "SELECT dids.number AS number, " + . "reseller_pricing.monthlycost AS monthlycost, " + . "reseller_pricing.prorate AS prorate, " + . "reseller_pricing.setup AS setup, " + . "reseller_pricing.cost AS cost, " + . "reseller_pricing.connectcost AS connectcost, " + . "reseller_pricing.includedseconds AS includedseconds, " + . "reseller_pricing.inc AS inc, " + . "reseller_pricing.disconnectionfee AS disconnectionfee, " + . "dids.provider AS provider, " + . "dids.country AS country, " + . "dids.city AS city, " + . "dids.province AS province, " + . "dids.extensions AS extensions, " + . "dids.account AS account, " + . "dids.variables AS variables, " + . "dids.options AS options, " + . "dids.maxchannels AS maxchannels, " + . "dids.chargeonallocation AS chargeonallocation, " + . "dids.allocation_bill_status AS allocation_bill_status, " + . "dids.limittime AS limittime, " + . "dids.dial_as AS dial_as, " + . "dids.status AS status " + . "FROM dids, reseller_pricing " + . "WHERE dids.number = " . $self->{_astpp_db}->quote($arg{did}) + . " AND reseller_pricing.type = '1' AND reseller_pricing.reseller = " + . $self->{_astpp_db}->quote($arg{reseller}) . " AND reseller_pricing.note = " + . $self->{_astpp_db}->quote($arg{did}); } print STDERR "$tmp\n"; $sql = @@ -1065,35 +1257,48 @@ return $diddata; } +=item $ASTPP->get_account() +Returns the details on the specified ASTPP account. It will search first by +"cardnum" then by "cc" and finally by "accountid". Accountid is the prefered +method but most installations use cardnum for legacy reasons. + +Example: + +$carddata = $ASTPP->get_account( + account => $params->{accountcode} +); + +=cut + sub get_account() { - my ($self, %arg) = @_; + my ($self, %arg) = @_; my ( $sql, $accountdata ); $sql = $self->{_astpp_db}->prepare( "SELECT * FROM accounts WHERE number = " - . $self->{_astpp_db}->quote($arg{account}) - . " AND status = 1" ); + . $self->{_astpp_db}->quote($arg{account}) + . " AND status = 1" ); $sql->execute; $accountdata = $sql->fetchrow_hashref; $sql->finish; if ($accountdata) { - return $accountdata; + return $accountdata; } else { $sql = $self->{_astpp_db}->prepare( "SELECT * FROM accounts WHERE cc = " - . $self->{_astpp_db}->quote($arg{account}) - . " AND status = 1" ); + . $self->{_astpp_db}->quote($arg{account}) + . " AND status = 1" ); $sql->execute; $accountdata = $sql->fetchrow_hashref; $sql->finish; } if ($accountdata) { - return $accountdata; + return $accountdata; } else { $sql = $self->{_astpp_db}->prepare( "SELECT * FROM accounts WHERE accountid = " - . $self->{_astpp_db}->quote($arg{account}) - . " AND status = 1" ); + . $self->{_astpp_db}->quote($arg{account}) + . " AND status = 1" ); $sql->execute; $accountdata = $sql->fetchrow_hashref; $sql->finish; @@ -1101,9 +1306,21 @@ } } -# Return data on specified pricelist +=item $ASTPP->get_pricelist() + +Returns the details on the specified pricelist. Is used both internally and +externally. + +Example: + +$pricelistdata = $ASTPP->get_pricelist( + account => $carddata->{pricelist} +); + +=cut + sub get_pricelist() { - my ($self, %arg) = @_; + my ($self, %arg) = @_; my $tmp = "SELECT * FROM pricelists WHERE name = " . $self->{_astpp_db}->quote($arg{pricelist}); my $sql = $self->{_astpp_db}->prepare($tmp); print STDERR "$tmp\n" . "\n"; @@ -1113,66 +1330,89 @@ return $pricelistdata; } +=item $ASTPP->max_length() +Returns the maximum allowable length for a call. + +Example: + +$max_length = $ASTPP->max_length( + account_pricelist => $carddata->{pricelist}, + account_credit_limit => $carddata->{creditlimit}, + account => $carddata->{number}, + destination => $destination, + call_max_length => $config->{call_max_length}, + max_free_length => $config->{max_free_length} +); + +=cut sub max_length() { - my ($self, %arg) = @_; - my ($branddata, $numdata, $credit, $credit_limit, $maxlength); - $branddata = &get_pricelist($self, pricelist => $arg{account_pricelist} ); # Fetch all the brand info from the db. + my ($self, %arg) = @_; + my ($branddata, $numdata, $credit, $credit_limit, $maxlength); + $branddata = &get_pricelist($self, pricelist => $arg{account_pricelist} ); # Fetch all the brand info from the db. + $numdata = &get_route($self, account => $arg{account}, destination => $arg{destination}, pricelist => $arg{account_pricelist} ); # Find the appropriate rate to charge the customer. - $numdata = &get_route($self, account => $arg{account}, destination => $arg{destination}, pricelist => $arg{account_pricelist} ); # Find the appropriate rate to charge the customer. - - if ( !$numdata->{pattern} ){ # If the pattern doesn't exist, we don't know what to charge the customer - # and therefore must exit. - print STDERR "CALLSTATUS 1\n" if $arg{debug} == 1; - print STDERR "INVALID PHONE NUMBER\n" if $arg{debug} == 1; - return (1,0); - } - print STDERR "Found pattern: $numdata->{pattern}\n"; - $credit = &accountbalance($self, account => $arg{account} ); # Find the available credit to the customer. - print STDERR "Account Balance: " . $credit * 10000; - $credit_limit = $arg{account_credit_limit} * 10000; - print STDERR "Credit Limit: $credit_limit"; - $credit = ($credit * -1) + ($credit_limit); # Add on the accounts credit limit. - #$credit = $credit / $arg{maxchannels} if $arg{maxchannels} > 0; - print STDERR "Credit: $credit \n"; - if ($arg{markup} > 0) { - $numdata->{connectcost} = - $numdata->{connectcost} * ( ( $arg{markup} / 10000 ) + 1 ); - $numdata->{cost} = - $numdata->{cost} * ( ( $arg{markup} / 10000 ) + 1 ); - } - if ( $numdata->{connectcost} > $credit ) { # If our connection fee is higher than the available money we can't connect. - return (0,0); - } - if ( $numdata->{cost} > 0 ) { - $maxlength = ( ( $credit - $numdata->{connectcost} ) / $numdata->{cost} ); - if ($arg{call_max_length} && $maxlength < $arg{call_max_length} / 1000){ - $maxlength = $arg{call_max_length} / 1000 / 60; - } - } - else { - $maxlength = $arg{max_free_length}; # If the call is set to be free then assign a max length. - } - if ( $numdata->{cost} > 0 ) { - $maxlength = ( ( $credit - $numdata->{connectcost} ) / $numdata->{cost} ); - if ($arg{call_max_length} && $maxlength < $arg{call_max_length} / 1000){ - $maxlength = $arg{call_max_length} / 1000 / 60; - } - } - else { - $maxlength = $arg{max_free_length}; # If the call is set to be free then assign a max length. - } - return (1, $maxlength,$numdata); + if ( !$numdata->{pattern} ){ # If the pattern doesn't exist, we don't know what to charge the customer + # and therefore must exit. + print STDERR "CALLSTATUS 1\n" if $arg{debug} == 1; + print STDERR "INVALID PHONE NUMBER\n" if $arg{debug} == 1; + return (1,0); + } + print STDERR "Found pattern: $numdata->{pattern}\n"; + $credit = &accountbalance($self, account => $arg{account} ); # Find the available credit to the customer. + print STDERR "Account Balance: " . $credit * 10000; + $credit_limit = $arg{account_credit_limit} * 10000; + print STDERR "Credit Limit: $credit_limit"; + $credit = ($credit * -1) + ($credit_limit); # Add on the accounts credit limit. + #$credit = $credit / $arg{maxchannels} if $arg{maxchannels} > 0; + print STDERR "Credit: $credit \n"; + if ($branddata->{markup} > 0) { + $numdata->{connectcost} = + $numdata->{connectcost} * ( ( $branddata->{markup} / 10000 ) + 1 ); + $numdata->{cost} = + $numdata->{cost} * ( ( $branddata->{markup} / 10000 ) + 1 ); + } + if ( $numdata->{connectcost} > $credit ) { # If our connection fee is higher than the available money we can't connect. + return (0,0); + } + if ( $numdata->{cost} > 0 ) { + $maxlength = ( ( $credit - $numdata->{connectcost} ) / $numdata->{cost} ); + if ($arg{call_max_length} && $maxlength < $arg{call_max_length} / 1000){ + $maxlength = $arg{call_max_length} / 1000 / 60; + } + } + else { + $maxlength = $arg{max_free_length}; # If the call is set to be free then assign a max length. + } + if ( $numdata->{cost} > 0 ) { + $maxlength = ( ( $credit - $numdata->{connectcost} ) / $numdata->{cost} ); + if ($arg{call_max_length} && $maxlength < $arg{call_max_length} / 1000){ + $maxlength = $arg{call_max_length} / 1000 / 60; + } + } + else { + $maxlength = $arg{max_free_length}; # If the call is set to be free then assign a max length. + } + return (1, $maxlength,$numdata); } +=item $ASTPP->accountbalance() +Return the balance for a specific ASTPP account. -# Return the balance for a specific ASTPP account. +Example: + +$balance .= $ASTPP->max_length( + account => $carddata->{number}, +); + +=cut + sub accountbalance() { - my ($self, %arg) = @_; + my ($self, %arg) = @_; my ( $tmp, $sql, $row, $debit, $credit, $balance, $posted_balance ); $tmp = - "SELECT SUM(debit) FROM cdrs WHERE cardnum= " + "SELECT SUM(debit) FROM cdrs WHERE cardnum= " . $self->{_astpp_db}->quote($arg{account}) . " AND status NOT IN (1, 2)"; $sql = $self->{_astpp_db}->prepare($tmp); @@ -1181,7 +1421,7 @@ $debit = $row->{"SUM(debit)"}; $sql->finish; $tmp = - "SELECT SUM(credit) FROM cdrs WHERE cardnum= " + "SELECT SUM(credit) FROM cdrs WHERE cardnum= " . $self->{_astpp_db}->quote($arg{account}) . " AND status NOT IN (1, 2)"; $sql = $self->{_astpp_db}->prepare($tmp); @@ -1203,85 +1443,113 @@ return $balance; } -# Return the appropriate "route" to use for determining costing on a call. + +=item $ASTPP->get_route() + +Return the appropriate "route" to use for determining costing on a call. This +is used both in rating as well as in determining the maximum length of a call. + +Example: + +$routeinfo = $ASTPP->get_route( + thirdlane_mods => $config->{thirdlane_mods}, + account => $carddata->{number}, #accountnumber + type => $userfield, # etc,etc + reseller => $carddata->{reseller}, + destination => $destination, #number we care calling + default_brand => $config->{default_brand} +); + +=cut + sub get_route() { my ($self, %arg) = @_; -# TEMPORARY -my $config; -$config->{thirdlane_mods} = 1; -# my ($branddata, $record, $sql, $tmp ); my $carddata = &get_account($self, account => $arg{account}); if ($arg{type} =~ /ASTPP-DID/) { - print STDERR "Call belongs to a DID.\n"; - $record = &get_did( reseller => $arg{reseller}, did => $arg{destination}); - $record->{comment} = $record->{city} . "," . $record->{province} . "," . $record->{country}; - $record->{pattern} = "DID:" . $arg{destination}; - $record->{pricelist} = $arg{pricelist}; - $branddata = &get_pricelist($self, pricelist => $arg{pricelist}); - print STDERR "pattern: $record->{pattern}\n" if $record->{pattern}; + print STDERR "Call belongs to a DID.\n"; + $record = &get_did( reseller => $arg{reseller}, did => $arg{destination}); + $record->{comment} = $record->{city} . "," . $record->{province} . "," . $record->{country}; + $record->{pattern} = "DID:" . $arg{destination}; + $record->{pricelist} = $arg{pricelist}; + $branddata = &get_pricelist($self, pricelist => $carddata->{pricelist}); + print STDERR "pattern: $record->{pattern}\n" if $record->{pattern}; } elsif ($config->{thirdlane_mods} == 1 && $arg{type} =~ m/.\d\d\d-IN/) { - print STDERR "Call belongs to a Thirdlane(tm) DID.\n"; - ($arg{destination} = $arg{type}) =~ s/-IN//g; - print STDERR "Destination: $arg{destination} \n"; - $record = &get_did( reseller => $arg{reseller}, did => $arg{destination}); - $record->{comment} = $record->{city} . "," . $record->{province} . "," . $record->{country}; $record->{pattern} = "DID:" . $arg{destination}; - $branddata = &get_pricelist($self, pricelist => $arg{pricelist}); - print STDERR "pattern: $record->{pattern}\n" if $record->{pattern}; + print STDERR "Call belongs to a Thirdlane(tm) DID.\n"; + ($arg{destination} = $arg{type}) =~ s/-IN//g; + print STDERR "Destination: $arg{destination} \n"; + $record = &get_did( reseller => $arg{reseller}, did => $arg{destination}); + $record->{comment} = $record->{city} . "," . $record->{province} . "," . $record->{country}; $record->{pattern} = "DID:" . $arg{destination}; + $branddata = &get_pricelist($self, pricelist => $carddata->{{pricelist}); + print STDERR "pattern: $record->{pattern}\n" if $record->{pattern}; } else { - my @pricelists = split ( m/,/m, $arg{pricelist} ); - foreach my $pricelistname (@pricelists) { - $pricelistname =~ s/"//g; #Strip off quotation marks - print STDERR "Pricelist: $pricelistname \n"; - $record = &search_for_route($self, destination => $arg{destination}, pricelist => $arg{pricelist}); - print STDERR "pattern: $record->{pattern}\n" if $record->{pattern}; - last if $record->{pattern}; #Returnes if we've found a match. - } + my @pricelists = split ( m/,/m, $carddata->{pricelist} ); + foreach my $pricelistname (@pricelists) { + $pricelistname =~ s/"//g; #Strip off quotation marks + print STDERR "Pricelist: $pricelistname \n"; + $record = &search_for_route($self, destination => $arg{destination}, pricelist => $arg{pricelist}); + print STDERR "pattern: $record->{pattern}\n" if $record->{pattern}; + last if $record->{pattern}; #Returnes if we've found a match. + } - while ( !$record->{pattern} && $carddata->{reseller} ) { - $carddata = &get_account($self, account => $carddata->{reseller}); - $record = &search_for_route($self, destination => $arg{destination}, pricelist => $arg{pricelist}); - print STDERR "pattern: $record->{pattern}\n" if $record->{pattern}; - } - if (!$record->{pattern}) { #If we still haven't found a match then we modify the dialed number as per the regular expressions set - # in the account. - my @regexs = split(m/","/m, $carddata->{dialed_modify}); - foreach my $regex (@regexs) { - $regex =~ s/"//g; #Strip off quotation marks - my ($grab,$replace) = split(m!/!i, $regex); # This will split the variable into a "grab" and "replace" as needed - print STDERR "Grab: $grab\n"; - print STDERR "Replacement: $replace\n"; - print STDERR "Phone Before: $arg{destination}\n"; - $arg{destination} =~ s/$grab/$replace/is; - print STDERR "Phone After: $arg{destination}\n"; - } - $record = &search_for_route($self, destination => $arg{destination}, pricelist => $arg{default_brand}); - print STDERR "pattern: $record->{pattern}\n" if $record->{pattern}; - } - if ( !$record->{pattern} ) { #If we have not found a route yet then we look in the "Default" pricelist. - $record = &search_for_route($self, destination => $arg{destination}, pricelist => $arg{default_brand}); - print STDERR "pattern: $record->{pattern}\n" if $record->{pattern}; - } - print STDERR "Route: $record->{comment} Cost: $record->{cost} Pricelist: $record->{pricelist} Pattern: $record->{pattern}\n" if $record; + while ( !$record->{pattern} && $carddata->{reseller} ) { + $carddata = &get_account($self, account => $carddata->{reseller}); + $record = &search_for_route($self, destination => $arg{destination}, pricelist => $arg{pricelist}); + print STDERR "pattern: $record->{pattern}\n" if $record->{pattern}; + } + if (!$record->{pattern}) { #If we still haven't found a match then we modify the dialed number as per the regular expressions set + # in the account. + my @regexs = split(m/","/m, $carddata->{dialed_modify}); + foreach my $regex (@regexs) { + $regex =~ s/"//g; #Strip off quotation marks + my ($grab,$replace) = split(m!/!i, $regex); # This will split the variable into a "grab" and "replace" as needed + print STDERR "Grab: $grab\n"; + print STDERR "Replacement: $replace\n"; + print STDERR "Phone Before: $arg{destination}\n"; + $arg{destination} =~ s/$grab/$replace/is; + print STDERR "Phone After: $arg{destination}\n"; + } + $record = &search_for_route($self, destination => $arg{destination}, pricelist => $arg{default_brand}); + print STDERR "pattern: $record->{pattern}\n" if $record->{pattern}; + } + if ( !$record->{pattern} ) { #If we have not found a route yet then we look in the "Default" pricelist. + $record = &search_for_route($self, destination => $arg{destination}, pricelist => $arg{default_brand}); + print STDERR "pattern: $record->{pattern}\n" if $record->{pattern}; + } + print STDERR "Route: $record->{comment} Cost: $record->{cost} Pricelist: $record->{pricelist} Pattern: $record->{pattern}\n" if $record; } if ( $record->{inc} eq "" || $record->{inc} == 0 ) { - $branddata = &get_pricelist($self, pricelist => $arg{pricelist}); - $record->{inc} = $branddata->{inc}; + $branddata = &get_pricelist($self, pricelist => $arg{pricelist}); + $record->{inc} = $branddata->{inc}; } return $record; } + +=item $ASTPP->search_for_route() + +Return the exact route. This is used internally and will only very rarely be +used outside of this module. + +Example: + +$routeinfo = $ASTPP->search_for_route( + pricelist => $carddata->{pricelist}, + reseller => $carddata->{reseller} +); + +=cut + sub search_for_route(){ -# my ($astpp_db,$config,$destination,$pricelist) = @_; my ($self, %arg) = @_; - my ($tmp,$sql,$record); + my ($tmp,$sql,$record); $tmp = "SELECT * FROM routes WHERE " - . $self->{_astpp_db}->quote($arg{destination}) - . " RLIKE pattern AND pricelist = " - . $self->{_astpp_db}->quote($arg{pricelist}) - . " ORDER BY LENGTH(pattern) DESC"; + . $self->{_astpp_db}->quote($arg{destination}) + . " RLIKE pattern AND pricelist = " + . $self->{_astpp_db}->quote($arg{pricelist}) + . " ORDER BY LENGTH(pattern) DESC"; print STDERR "$tmp\n"; $sql = $self->{_astpp_db}->prepare($tmp); @@ -1291,47 +1559,14 @@ return $record; }; +1; - -# Preloaded methods go here. - -1; __END__ -# Below is stub documentation for your module. You'd better edit it! -=head1 NAME - -ASTPP - Perl extension for ASTPP (www.astpp.org) - -=head1 SYNOPSIS - - use ASTPP; - -=head1 DESCRIPTION - -Stub documentation for ASTPP, created by h2xs. It looks like the -author of the extension was negligent enough to leave the stub -unedited. - -Blah blah blah. - -=head2 EXPORT - -None by default. - - - =head1 SEE ALSO -Mention other useful documentation such as the documentation of -related modules or operating system documentation (such as man pages -in UNIX), or any relevant external documentation such as RFCs or -standards. +For more information visit our website at (www.astpp.org) -If you have a mailing list set up for your module, mention it here. - -If you have a web site set up for your module, mention it here. - =head1 AUTHOR Darren Wiebe, E<lt>da...@al...E<gt> @@ -1340,9 +1575,6 @@ Copyrig... [truncated message content] |