diff options
author | Ivan Kohler <ivan-debian@420.am> | 2012-03-15 13:56:48 -0700 |
---|---|---|
committer | Ivan Kohler <ivan-debian@420.am> | 2012-03-15 13:56:48 -0700 |
commit | 7d68066ea33f9f85fe14ce663372642d7ec2ad20 (patch) | |
tree | f659173a23d541da3032f8a8156f888810d7efda /FS | |
parent | d622dc369cc0856fb791658b35f889470a7da605 (diff) | |
parent | a69299c596de60f4b26db7431165f7f3ffe928e2 (diff) |
Merge branch 'master' of git.freeside.biz:/home/git/freeside
Diffstat (limited to 'FS')
-rw-r--r-- | FS/FS/ClientAPI/MyAccount.pm | 4 | ||||
-rw-r--r-- | FS/FS/Schema.pm | 2 | ||||
-rw-r--r-- | FS/FS/cdr.pm | 4 | ||||
-rw-r--r-- | FS/FS/detail_format.pm | 1 | ||||
-rw-r--r-- | FS/FS/part_event.pm | 9 | ||||
-rw-r--r-- | FS/FS/part_event/Condition/signupdate_day.pm | 54 | ||||
-rwxr-xr-x | FS/FS/router.pm | 9 | ||||
-rw-r--r-- | FS/FS/svc_acct.pm | 3 | ||||
-rwxr-xr-x | FS/FS/svc_broadband.pm | 77 | ||||
-rw-r--r-- | FS/FS/svc_hardware.pm | 2 |
10 files changed, 135 insertions, 30 deletions
diff --git a/FS/FS/ClientAPI/MyAccount.pm b/FS/FS/ClientAPI/MyAccount.pm index 7d177f9fe..acd0c6e85 100644 --- a/FS/FS/ClientAPI/MyAccount.pm +++ b/FS/FS/ClientAPI/MyAccount.pm @@ -2485,7 +2485,7 @@ sub myaccount_passwd { unless $svc_acct->check_password($p->{'old_password'}); } - $svc_acct->_password($p->{'new_password'}); + $svc_acct->set_password($p->{'new_password'}); my $error = $svc_acct->replace(); my($label, $value) = $svc_acct->cust_svc->label; @@ -2626,7 +2626,7 @@ sub process_reset_passwd { my $svc_acct = qsearchs('svc_acct', { 'svcnum' => $svcnum } ) or return { 'error' => "Service not found" }; - $svc_acct->_password($p->{'new_password'}); + $svc_acct->set_password($p->{'new_password'}); my $error = $svc_acct->replace(); my($label, $value) = $svc_acct->cust_svc->label; diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 1112f52d7..a36d2dcdb 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -2484,7 +2484,7 @@ sub tables_hashref { 'routername', 'varchar', '', $char_d, '', '', 'svcnum', 'int', 'NULL', '', '', '', 'agentnum', 'int', 'NULL', '', '', '', - 'auto_addr', 'char', 'NULL', 1, '', '', + 'manual_addr', 'char', 'NULL', 1, '', '', ], 'primary_key' => 'routernum', 'unique' => [], diff --git a/FS/FS/cdr.pm b/FS/FS/cdr.pm index 1769fe9c1..3a6b01ba5 100644 --- a/FS/FS/cdr.pm +++ b/FS/FS/cdr.pm @@ -152,7 +152,7 @@ following fields are currently supported: =item svcnum - Link to customer service (see L<FS::cust_svc>) -=item freesidestatus - NULL, processing-tiered, rated, done +=item freesidestatus - NULL, processing-tiered, rated, done, skipped, no-charge, failed =item freesiderewritestatus - NULL, done, skipped @@ -545,7 +545,7 @@ sub rate_prefix { ); if ( $reason ) { warn "not charging for CDR ($reason)\n" if $DEBUG; - return $self->set_status_and_rated_price( 'rated', + return $self->set_status_and_rated_price( 'skipped', 0, $opt{'svcnum'}, ); diff --git a/FS/FS/detail_format.pm b/FS/FS/detail_format.pm index f70acc663..88cc02f83 100644 --- a/FS/FS/detail_format.pm +++ b/FS/FS/detail_format.pm @@ -235,6 +235,7 @@ sub duration { my $cdr = shift; my $object = $self->{inbound} ? $cdr->cdr_termination(1) : $cdr; my $sec = $object->rated_seconds if $object; + $sec ||= 0; # XXX termination objects don't have rated_granularity so this may # result in inbound CDRs being displayed as min/sec when they shouldn't. # Should probably fix this. diff --git a/FS/FS/part_event.pm b/FS/FS/part_event.pm index 31d2afd23..62f16fa1c 100644 --- a/FS/FS/part_event.pm +++ b/FS/FS/part_event.pm @@ -253,7 +253,7 @@ sub templatename { } } -=item targets +=item targets OPTIONS Returns all objects (of type C<FS::eventtable>, for this object's C<eventtable>) eligible for processing under this event, as of right now. @@ -268,7 +268,8 @@ but can be useful when configuring events. sub targets { my $self = shift; - my $time = time; # $opt{'time'}? + my %opt = @_; + my $time = $opt{'time'} || time; my $eventpart = $self->eventpart; $eventpart =~ /^\d+$/ or die "bad eventpart $eventpart"; @@ -305,8 +306,8 @@ sub targets { }); my @tested_objects; foreach my $object ( @objects ) { - my $cust_event = $self->new_cust_event($object, 'time' => $time); - next unless $cust_event->test_conditions; + my $cust_event = $self->new_cust_event($object); + next unless $cust_event->test_conditions('time' => $time); $object->set('cust_event', $cust_event); push @tested_objects, $object; diff --git a/FS/FS/part_event/Condition/signupdate_day.pm b/FS/FS/part_event/Condition/signupdate_day.pm new file mode 100644 index 000000000..dbe9e60a1 --- /dev/null +++ b/FS/FS/part_event/Condition/signupdate_day.pm @@ -0,0 +1,54 @@ +package FS::part_event::Condition::signupdate_day; + +use strict; +use Tie::IxHash; + +use base qw( FS::part_event::Condition ); + +sub description { + "Customer signed up on the same day of month as today"; +} + +sub option_fields { + ( + 'delay' => { label => 'Delay additional days', + type => 'text', + value => '0', + }, + ); +} + +sub condition { + my( $self, $object, %opt ) = @_; + + my $cust_main = $self->cust_main($object); + + my ($today) = (localtime($opt{'time'}))[3]; + + my $delay = $self->option('delay') || 0; + my $signupday = ((localtime($cust_main->signupdate + $delay * 86400))[3] - 1) + % 28 + 1; + + $today == $signupday; +} + +sub condition_sql { + my( $class, $table, %opt ) = @_; + my $mday; + if ( $opt{'driver_name'} eq 'Pg' ) { + $mday = sub{ "EXTRACT( DAY FROM TO_TIMESTAMP($_[0]) )::INTEGER" }; + } + elsif ( $opt{'driver_name'} eq 'mysql' ) { + $mday = sub{ "DAY( FROM_UNIXTIME($_[0]) )" }; + } + else { + return 'true'; + } + + my $delay = $class->condition_sql_option_integer('delay', + $opt{'driver_name'}); # returns 0 for null + $mday->($opt{'time'}) . ' = '. + '(' . $mday->("cust_main.signupdate + $delay * 86400") . ' - 1) % 28 + 1'; +} + +1; diff --git a/FS/FS/router.pm b/FS/FS/router.pm index 99373e5d1..6fa44b408 100755 --- a/FS/FS/router.pm +++ b/FS/FS/router.pm @@ -40,8 +40,9 @@ fields are currently supported: =item svcnum - svcnum of the owning FS::svc_broadband, if appropriate -=item auto_addr - flag to automatically assign IP addresses to services -linked to this router ('Y' or null). +=item manual_addr - set to 'Y' to allow services linked to this router +to have any IP address, rather than one in an address block belonging +to the router. =back @@ -86,7 +87,7 @@ sub check { my $error = $self->ut_numbern('routernum') || $self->ut_text('routername') - || $self->ut_enum('auto_addr', [ '', 'Y' ]) + || $self->ut_enum('manual_addr', [ '', 'Y' ]) || $self->ut_agentnum_acl('agentnum', 'Broadband global configuration') ; return $error if $error; @@ -146,7 +147,7 @@ sub addr_block { sub auto_addr_block { my $self = shift; - return () if !$self->auto_addr; + return () if $self->manual_addr; return qsearch('addr_block', { routernum => $self->routernum, manual_flag => '' }); } diff --git a/FS/FS/svc_acct.pm b/FS/FS/svc_acct.pm index 139f92715..e67db43c6 100644 --- a/FS/FS/svc_acct.pm +++ b/FS/FS/svc_acct.pm @@ -2524,7 +2524,8 @@ sub check_password { if ( $self->_password_encoding eq 'ldap' ) { - my $auth = from_rfc2307 Authen::Passphrase $self->_password; + $password =~ s/^{PLAIN}/{CLEARTEXT}/; + my $auth = from_rfc2307 Authen::Passphrase $password; return $auth->match($check_password); } elsif ( $self->_password_encoding eq 'crypt' ) { diff --git a/FS/FS/svc_broadband.pm b/FS/FS/svc_broadband.pm index 109620011..212a4bf24 100755 --- a/FS/FS/svc_broadband.pm +++ b/FS/FS/svc_broadband.pm @@ -135,7 +135,7 @@ sub table_info { sub table { 'svc_broadband'; } -sub table_dupcheck_fields { ( 'mac_addr' ); } +sub table_dupcheck_fields { ( 'ip_addr', 'mac_addr' ); } =item search HASHREF @@ -406,7 +406,13 @@ sub check { } my $agentnum = $cust_pkg->cust_main->agentnum if $cust_pkg; - if ($self->routernum) { + if ( $conf->exists('auto_router') and $self->ip_addr and !$self->routernum ) { + # assign_router is guaranteed to provide a router that's legal + # for this agent and svcpart + my $error = $self->_check_ip_addr || $self->assign_router; + return $error if $error; + } + elsif ($self->routernum) { return "Router ".$self->routernum." does not provide this service" unless qsearchs('part_svc_router', { svcpart => $svcpart, @@ -417,16 +423,19 @@ sub check { return "Router ".$self->routernum." does not serve this customer" if $router->agentnum and $router->agentnum != $agentnum; - if ( $router->auto_addr ) { + if ( $router->manual_addr ) { + $self->blocknum(''); + } + else { my $addr_block = $self->addr_block; unless ( $addr_block and $addr_block->manual_flag ) { my $error = $self->assign_ip_addr; return $error if $error; } } - else { - $self->blocknum(''); - } + + my $error = $self->_check_ip_addr; + return $error if $error; } # if $self->routernum if ( $cust_pkg && ! $self->latitude && ! $self->longitude ) { @@ -440,15 +449,12 @@ sub check { } } - $error = $self->_check_ip_addr; - return $error if $error; - $self->SUPER::check; } =item assign_ip_addr -Assign an address block matching the selected router, and the selected block +Assign an IP address matching the selected router, and the selected block if there is one. =cut @@ -469,6 +475,7 @@ sub assign_ip_addr { else { return ''; } +#warn "assigning ip address in blocks\n".join("\n",map{$_->cidr} @blocks)."\n"; foreach my $block ( @blocks ) { if ( $self->ip_addr and $block->NetAddr->contains($self->NetAddr) ) { @@ -487,6 +494,29 @@ sub assign_ip_addr { } } +=item assign_router + +Assign an address block and router matching the selected IP address. +Does nothing if IP address is null. + +=cut + +sub assign_router { + my $self = shift; + return '' if !$self->ip_addr; + #warn "assigning router/block for ".$self->ip_addr."\n"; + foreach my $router ($self->allowed_routers) { + foreach my $block ($router->addr_block) { + if ( $block->NetAddr->contains($self->NetAddr) ) { + $self->blocknum($block->blocknum); + $self->routernum($block->routernum); + return ''; + } + } + } + return $self->ip_addr.' is not in an allowed block.'; +} + sub _check_ip_addr { my $self = shift; @@ -494,6 +524,9 @@ sub _check_ip_addr { return '' if $conf->exists('svc_broadband-allow_null_ip_addr'); return 'IP address required'; } + else { + return 'Cannot parse address: '.$self->ip_addr unless $self->NetAddr; + } # if (my $dup = qsearchs('svc_broadband', { # ip_addr => $self->ip_addr, # svcnum => {op=>'!=', value => $self->svcnum} @@ -506,10 +539,17 @@ sub _check_ip_addr { sub _check_duplicate { my $self = shift; - return "MAC already in use" - if ( $self->mac_addr && - scalar( qsearch( 'svc_broadband', { 'mac_addr', $self->mac_addr } ) ) - ); + $self->lock_table; + + my @dup; + @dup = $self->find_duplicates('global', 'ip_addr'); + if ( @dup ) { + return "IP address in use (svcnum ".$dup[0]->svcnum.")"; + } + @dup = $self->find_duplicates('global', 'mac_addr'); + if ( @dup ) { + return "MAC address in use (svcnum ".$dup[0]->svcnum.")"; + } ''; } @@ -558,8 +598,15 @@ Returns a list of allowed FS::router objects. sub allowed_routers { my $self = shift; my $svcpart = $self->svcnum ? $self->cust_svc->svcpart : $self->svcpart; - map { $_->router } qsearch('part_svc_router', + my @r = map { $_->router } qsearch('part_svc_router', { svcpart => $self->cust_svc->svcpart }); + if ( $self->cust_main ) { + my $agentnum = $self->cust_main->agentnum; + return grep { !$_->agentnum or $_->agentnum == $agentnum } @r; + } + else { + return @r; + } } =back diff --git a/FS/FS/svc_hardware.pm b/FS/FS/svc_hardware.pm index b4eb8ccfa..22e627538 100644 --- a/FS/FS/svc_hardware.pm +++ b/FS/FS/svc_hardware.pm @@ -164,7 +164,7 @@ sub check { if ( $conf->exists('svc_hardware-check_mac_addr') ) { $hw_addr = uc($hw_addr); $hw_addr =~ /^[0-9A-F]{12}$/ - or return "Illegal (MAC address) ".$self->getfield('hw_addr'); + or return "Illegal (MAC address) '".$self->getfield('hw_addr')."'"; } $self->setfield('hw_addr', $hw_addr); |