communigate provisioning phase 2: Domain:Account Defaults:Settings: RulesAllowed...
[freeside.git] / FS / FS / rate.pm
index b8a6940..6430ff0 100644 (file)
@@ -1,12 +1,14 @@
 package FS::rate;
 
 use strict;
-use vars qw( @ISA );
-use FS::Record qw( qsearch qsearchs dbh );
+use vars qw( @ISA $DEBUG );
+use FS::Record qw( qsearch qsearchs dbh fields );
 use FS::rate_detail;
 
 @ISA = qw(FS::Record);
 
+$DEBUG = 0;
+
 =head1 NAME
 
 FS::rate - Object methods for rate records
@@ -94,13 +96,32 @@ sub insert {
   }
 
   if ( $options{'rate_detail'} ) {
+
+    my( $num, $last, $min_sec ) = (0, time, 5); #progressbar foo
+
     foreach my $rate_detail ( @{$options{'rate_detail'}} ) {
+
       $rate_detail->ratenum($self->ratenum);
       $error = $rate_detail->insert;
       if ( $error ) {
         $dbh->rollback if $oldAutoCommit;
         return $error;
       }
+
+      if ( $options{'job'} ) {
+        $num++;
+        if ( time - $min_sec > $last ) {
+          my $error = $options{'job'}->update_statustext(
+            int( 100 * $num / scalar( @{$options{'rate_detail'}} ) )
+          );
+          if ( $error ) {
+            $dbh->rollback if $oldAutoCommit;
+            return $error;
+          }
+          $last = time;
+        }
+      }
+
     }
   }
 
@@ -148,8 +169,8 @@ sub replace {
   local $FS::UID::AutoCommit = 0;
   my $dbh = dbh;
 
-  my @old_rate_detail = ();
-  @old_rate_detail = $old->rate_detail if $options{'rate_detail'};
+#  my @old_rate_detail = ();
+#  @old_rate_detail = $old->rate_detail if $options{'rate_detail'};
 
   my $error = $new->SUPER::replace($old);
   if ($error) {
@@ -157,21 +178,67 @@ sub replace {
     return $error;
   }
 
-  foreach my $old_rate_detail ( @old_rate_detail ) {
-    my $error = $old_rate_detail->delete;
-    if ($error) {
+#  foreach my $old_rate_detail ( @old_rate_detail ) {
+#
+#    my $error = $old_rate_detail->delete;
+#    if ($error) {
+#      $dbh->rollback if $oldAutoCommit;
+#      return $error;
+#    }
+#
+#    if ( $options{'job'} ) {
+#      $num++;
+#      if ( time - $min_sec > $last ) {
+#        my $error = $options{'job'}->update_statustext(
+#          int( 50 * $num / scalar( @old_rate_detail ) )
+#        );
+#        if ( $error ) {
+#          $dbh->rollback if $oldAutoCommit;
+#          return $error;
+#        }
+#        $last = time;
+#      }
+#    }
+#
+#  }
+  if ( $options{'rate_detail'} ) {
+    my $sth = $dbh->prepare('DELETE FROM rate_detail WHERE ratenum = ?') or do {
       $dbh->rollback if $oldAutoCommit;
-      return $error;
-    }
-  }
-
-  foreach my $rate_detail ( @{$options{'rate_detail'}} ) {
-    $rate_detail->ratenum($new->ratenum);
-    $error = $rate_detail->insert;
-    if ( $error ) {
+      return $dbh->errstr;
+    };
+  
+    $sth->execute($old->ratenum) or do {
       $dbh->rollback if $oldAutoCommit;
-      return $error;
+      return $sth->errstr;
+    };
+
+    my( $num, $last, $min_sec ) = (0, time, 5); #progresbar foo
+#  $num = 0;
+    foreach my $rate_detail ( @{$options{'rate_detail'}} ) {
+  
+      $rate_detail->ratenum($new->ratenum);
+      $error = $rate_detail->insert;
+      if ( $error ) {
+        $dbh->rollback if $oldAutoCommit;
+        return $error;
+      }
+  
+      if ( $options{'job'} ) {
+        $num++;
+        if ( time - $min_sec > $last ) {
+          my $error = $options{'job'}->update_statustext(
+            int( 100 * $num / scalar( @{$options{'rate_detail'}} ) )
+          );
+          if ( $error ) {
+            $dbh->rollback if $oldAutoCommit;
+            return $error;
+          }
+          $last = time;
+        }
+      }
+  
     }
+
   }
 
   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
@@ -202,16 +269,52 @@ sub check {
   $self->SUPER::check;
 }
 
-=item dest_detail REGIONNUM | RATE_REGION_OBJECTD
+=item dest_detail REGIONNUM | RATE_REGION_OBJECTD | HASHREF
 
 Returns the rate detail (see L<FS::rate_detail>) for this rate to the
-specificed destination.
+specificed destination.  Destination can be specified as an FS::rate_detail
+object or regionnum (see L<FS::rate_detail>), or as a hashref with two keys:
+I<countrycode> and I<phonenum>.
 
 =cut
 
 sub dest_detail {
   my $self = shift;
-  my $regionnum = ref($_[0]) ? shift->regionnum : shift;
+
+  my $regionnum;
+  if ( ref($_[0]) eq 'HASH' ) {
+
+    my $countrycode = $_[0]->{'countrycode'};
+    my $phonenum    = $_[0]->{'phonenum'};
+
+    #find a rate prefix, first look at most specific (4 digits) then 3, etc.,
+    # finally trying the country code only
+    my $rate_prefix = '';
+    for my $len ( reverse(1..10) ) {
+      $rate_prefix = qsearchs('rate_prefix', {
+        'countrycode' => $countrycode,
+        #'npa'         => { op=> 'LIKE', value=> substr($number, 0, $len) }
+        'npa'         => substr($phonenum, 0, $len),
+      } ) and last;
+    }
+    $rate_prefix ||= qsearchs('rate_prefix', {
+      'countrycode' => $countrycode,
+      'npa'         => '',
+    });
+
+    #
+    #die "Can't find rate for call $to_or_from +$countrycode $number\n"
+    die "Can't find rate for +$countrycode $phonenum\n"
+      unless $rate_prefix;
+
+    $regionnum = $rate_prefix->regionnum;
+
+    #$rate_region = $rate_prefix->rate_region;
+
+  } else {
+    $regionnum = ref($_[0]) ? shift->regionnum : shift;
+  }
+
   qsearchs( 'rate_detail', { 'ratenum'        => $self->ratenum,
                              'dest_regionnum' => $regionnum,     } );
 }
@@ -230,6 +333,76 @@ sub rate_detail {
 
 =back
 
+=head1 SUBROUTINES
+
+=over 4
+
+=item process
+
+Experimental job-queue processor for web interface adds/edits
+
+=cut
+
+use Storable qw(thaw);
+use Data::Dumper;
+use MIME::Base64;
+sub process {
+  my $job = shift;
+
+  my $param = thaw(decode_base64(shift));
+  warn Dumper($param) if $DEBUG;
+
+  my $old = qsearchs('rate', { 'ratenum' => $param->{'ratenum'} } )
+    if $param->{'ratenum'};
+
+  my @rate_detail = map {
+
+    my $regionnum = $_->regionnum;
+    if ( $param->{"sec_granularity$regionnum"} ) {
+
+      new FS::rate_detail {
+        'dest_regionnum'  => $regionnum,
+        map { $_ => $param->{"$_$regionnum"} }
+            qw( min_included min_charge sec_granularity )
+      };
+
+    } else {
+
+      new FS::rate_detail {
+        'dest_regionnum'  => $regionnum,
+        'min_included'    => 0,
+        'min_charge'      => 0,
+        'sec_granularity' => '60'
+      };
+
+    }
+    
+  } qsearch('rate_region', {} );
+  
+  my $rate = new FS::rate {
+    map { $_ => $param->{$_} }
+        fields('rate')
+  };
+
+  my $error = '';
+  if ( $param->{'ratenum'} ) {
+    warn "$rate replacing $old (". $param->{'ratenum'}. ")\n" if $DEBUG;
+    $error = $rate->replace( $old,
+                             'rate_detail' => \@rate_detail,
+                             'job'         => $job,
+                           );
+  } else {
+    warn "inserting $rate\n" if $DEBUG;
+    $error = $rate->insert( 'rate_detail' => \@rate_detail,
+                            'job'         => $job,
+                          );
+    #$ratenum = $rate->getfield('ratenum');
+  }
+
+  die "$error\n" if $error;
+
+}
+
 =head1 BUGS
 
 =head1 SEE ALSO