working job dependancies
authorivan <ivan>
Fri, 14 Jun 2002 11:22:53 +0000 (11:22 +0000)
committerivan <ivan>
Fri, 14 Jun 2002 11:22:53 +0000 (11:22 +0000)
FS::queue::joblisting html excapes & truncates long arguments
welcome email (sheesh!) closes: Bug#420 (haha at 4:20 am, too.  really!)

FS/FS/Conf.pm
FS/FS/cust_main.pm
FS/FS/queue.pm
FS/FS/svc_Common.pm
FS/FS/svc_acct.pm
FS/bin/freeside-queued

index 1264617..dbb3682 100644 (file)
@@ -249,15 +249,15 @@ httemplate/docs/config.html
 
   {
     'key'         => 'bindprimary',
-    'section'     => 'BIND',
-    'description' => 'Your BIND primary nameserver.  This enables export of /var/named/named.conf and zone files into /var/named',
+    'section'     => 'deprecated',
+    'description' => '<b>DEPRECATED</b>, add a <i>bind</i> <a href="../browse/part_export.cgi">export</a> instead.  Your BIND primary nameserver.  This enables export of /var/named/named.conf and zone files into /var/named',
     'type'        => 'text',
   },
 
   {
     'key'         => 'bindsecondaries',
-    'section'     => 'BIND',
-    'description' => 'Your BIND secondary nameservers, one per line.  This enables export of /var/named/named.conf',
+    'section'     => 'deprecated',
+    'description' => '<b>DEPRECATED</b>, add a <i>bind_slave</i> <a href="../browse/part_export.cgi">export</a> instead.  Your BIND secondary nameservers, one per line.  This enables export of /var/named/named.conf',
     'type'        => 'textarea',
   },
 
@@ -277,8 +277,8 @@ httemplate/docs/config.html
 
   {
     'key'         => 'bsdshellmachines',
-    'section'     => 'shell',
-    'description' => 'Your BSD flavored shell (and mail) machines, one per line.  This enables export of `/etc/passwd\' and `/etc/master.passwd\'.',
+    'section'     => 'deprecated',
+    'description' => '<b>DEPRECATED</b>, add a <i>bsdshell</i> <a href="../browse/part_export.cgi">export</a> instead.  Your BSD flavored shell (and mail) machines, one per line.  This enables export of `/etc/passwd\' and `/etc/master.passwd\'.',
     'type'        => 'textarea',
   },
 
@@ -506,8 +506,8 @@ httemplate/docs/config.html
 
   {
     'key'         => 'nismachines',
-    'section'     => 'shell',
-    'description' => 'Your NIS master (not slave master) machines, one per line.  This enables export of `/etc/global/passwd\' and `/etc/global/shadow\'.',
+    'section'     => 'deprecated',
+    'description' => '<b>DEPRECATED</b>.  Your NIS master (not slave master) machines, one per line.  This enables export of `/etc/global/passwd\' and `/etc/global/shadow\'.',
     'type'        => 'textarea',
   },
 
@@ -633,8 +633,8 @@ httemplate/docs/config.html
 
   {
     'key'         => 'shellmachines',
-    'section'     => 'shell',
-    'description' => 'Your Linux and System V flavored shell (and mail) machines, one per line.  This enables export of `/etc/passwd\' and `/etc/shadow\' files.',
+    'section'     => 'deprecated',
+    'description' => '<b>DEPRECATED</b>, add a <i>sysvshell</i> <a href="../browse/part_export.cgi">export</a> instead.  Your Linux and System V flavored shell (and mail) machines, one per line.  This enables export of `/etc/passwd\' and `/etc/shadow\' files.',
      'type'        => 'textarea',
  },
 
@@ -937,6 +937,35 @@ httemplate/docs/config.html
     'type'        => 'checkbox',
   },
 
+  {
+    'key'         => 'welcome_email',
+    'section'     => '',
+    'description' => 'Template file for welcome email.  Welcome emails are sent to the customer email invoice destination(s) each time a svc_acct record is created.  See the <a href="http://search.cpan.org/doc/MJD/Text-Template-1.42/Template.pm">Text::Template</a> documentation for details on the template substitution language.  The following variables are available: <code>$username</code>, <code>$password</code>, <code>$first</code>, <code>$last</code> and <code>$pkg</code>.',
+    'type'        => 'textarea',
+  },
+
+  {
+    'key'         => 'welcome_email-from',
+    'section'     => '',
+    'description' => 'From: address header for welcome email',
+    'type'        => 'text',
+  },
+
+  {
+    'key'         => 'welcome_email-subject',
+    'section'     => '',
+    'description' => 'Subject: header for welcome email',
+    'type'        => 'text',
+  },
+  
+  {
+    'key'         => 'welcome_email-mimetype',
+    'section'     => '',
+    'description' => 'MIME type for welcome email',
+    'type'        => 'select',
+    'select_enum' => [ 'text/plain', 'text/html' ],
+  },
+
 );
 
 1;
index 6be6cdb..b39a77f 100644 (file)
@@ -220,7 +220,8 @@ invoicing_list destination to the newly-created svc_acct.  Here's an example:
 
 sub insert {
   my $self = shift;
-  my @param = @_;
+  my $cust_pkgs = @_ ? shift : {};
+  my $invoicing_list = @_ ? shift : '';
 
   local $SIG{HUP} = 'IGNORE';
   local $SIG{INT} = 'IGNORE';
@@ -261,27 +262,35 @@ sub insert {
     return $error;
   }
 
-  if ( @param ) { # CUST_PKG_HASHREF
-    my $cust_pkgs = shift @param;
-    foreach my $cust_pkg ( keys %$cust_pkgs ) {
-      $cust_pkg->custnum( $self->custnum );
-      $error = $cust_pkg->insert;
+  # invoicing list
+  if ( $invoicing_list ) {
+    $error = $self->check_invoicing_list( $invoicing_list );
+    if ( $error ) {
+      $dbh->rollback if $oldAutoCommit;
+      return "checking invoicing_list (transaction rolled back): $error";
+    }
+    $self->invoicing_list( $invoicing_list );
+  }
+
+  # packages
+  foreach my $cust_pkg ( keys %$cust_pkgs ) {
+    $cust_pkg->custnum( $self->custnum );
+    $error = $cust_pkg->insert;
+    if ( $error ) {
+      $dbh->rollback if $oldAutoCommit;
+      return "inserting cust_pkg (transaction rolled back): $error";
+    }
+    foreach my $svc_something ( @{$cust_pkgs->{$cust_pkg}} ) {
+      $svc_something->pkgnum( $cust_pkg->pkgnum );
+      if ( $seconds && $svc_something->isa('FS::svc_acct') ) {
+        $svc_something->seconds( $svc_something->seconds + $seconds );
+        $seconds = 0;
+      }
+      $error = $svc_something->insert;
       if ( $error ) {
         $dbh->rollback if $oldAutoCommit;
-        return "inserting cust_pkg (transaction rolled back): $error";
-      }
-      foreach my $svc_something ( @{$cust_pkgs->{$cust_pkg}} ) {
-        $svc_something->pkgnum( $cust_pkg->pkgnum );
-        if ( $seconds && $svc_something->isa('FS::svc_acct') ) {
-          $svc_something->seconds( $svc_something->seconds + $seconds );
-          $seconds = 0;
-        }
-        $error = $svc_something->insert;
-        if ( $error ) {
-          $dbh->rollback if $oldAutoCommit;
-          #return "inserting svc_ (transaction rolled back): $error";
-          return $error;
-        }
+        #return "inserting svc_ (transaction rolled back): $error";
+        return $error;
       }
     }
   }
@@ -291,16 +300,6 @@ sub insert {
     return "No svc_acct record to apply pre-paid time";
   }
 
-  if ( @param ) { # INVOICING_LIST_ARYREF
-    my $invoicing_list = shift @param;
-    $error = $self->check_invoicing_list( $invoicing_list );
-    if ( $error ) {
-      $dbh->rollback if $oldAutoCommit;
-      return "checking invoicing_list (transaction rolled back): $error";
-    }
-    $self->invoicing_list( $invoicing_list );
-  }
-
   if ( $amount ) {
     my $cust_credit = new FS::cust_credit {
       'custnum' => $self->custnum,
index df92c56..1de19b7 100644 (file)
@@ -1,7 +1,7 @@
 package FS::queue;
 
 use strict;
-use vars qw( @ISA @EXPORT_OK $conf );
+use vars qw( @ISA @EXPORT_OK $conf $jobnums);
 use Exporter;
 use FS::UID;
 use FS::Conf;
@@ -18,6 +18,8 @@ $FS::UID::callback{'FS::queue'} = sub {
   $conf = new FS::Conf;
 };
 
+$jobnums = '';
+
 =head1 NAME
 
 FS::queue - Object methods for queue records
@@ -118,6 +120,8 @@ sub insert {
     }
   }
 
+  push @$jobnums, $self->jobnum if $jobnums;
+
   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
 
   '';
@@ -257,10 +261,10 @@ in a database transaction.
 
 sub depend_insert {
   my($self, $other_jobnum) = @_;
-  my $queue_depend = new FS::queue_depend (
+  my $queue_depend = new FS::queue_depend ( {
     'jobnum'        => $self->jobnum,
     'depend_jobnum' => $other_jobnum,
-  );
+  );
   $queue_depend->insert;
 }
 
@@ -278,6 +282,7 @@ sub joblisting {
   my($hashref, $noactions) = @_;
 
   use Date::Format;
+  use HTML::Entities;
   use FS::CGI;
 
   my @queue = qsearch( 'queue', $hashref );
@@ -308,7 +313,9 @@ END
 
     my $args;
     if ( $dangerous || $queue->job !~ /^FS::part_export::/ || !$noactions ) {
-      $args = join(' ', $queue->args);
+      $args = encode_entities( join(' ',
+        map { length($_)<54 ? $_ : substr($_,0,32)."..."  } $queue->args #1&g
+      ) );
     } else {
       $args = '';
     }
@@ -318,7 +325,7 @@ END
     $status .= ': '. $queue->statustext if $queue->statustext;
     my @queue_depend = $queue->queue_depend;
     $status .= ' (waiting for '.
-               join(', ', map { $_->other_jobnum } @queue_depend ). 
+               join(', ', map { $_->depend_jobnum } @queue_depend ). 
                ')'
       if @queue_depend;
     my $changable = $dangerous
@@ -378,10 +385,12 @@ END
 
 =head1 VERSION
 
-$Id: queue.pm,v 1.13 2002-05-15 14:00:32 ivan Exp $
+$Id: queue.pm,v 1.14 2002-06-14 11:22:53 ivan Exp $
 
 =head1 BUGS
 
+$jobnums global
+
 =head1 SEE ALSO
 
 L<FS::Record>, schema.html from the base documentation.
index cd278ef..87b6097 100644 (file)
@@ -5,6 +5,7 @@ use vars qw( @ISA $noexport_hack );
 use FS::Record qw( qsearchs fields dbh );
 use FS::cust_svc;
 use FS::part_svc;
+use FS::queue;
 
 @ISA = qw( FS::Record );
 
@@ -27,7 +28,7 @@ inherit from, i.e. FS::svc_acct.  FS::svc_Common inherits from FS::Record.
 
 =over 4
 
-=item insert
+=item insert [ JOBNUM_ARRAYREF ]
 
 Adds this record to the database.  If there is an error, returns the error,
 otherwise returns false.
@@ -35,10 +36,14 @@ otherwise returns false.
 The additional fields pkgnum and svcpart (see L<FS::cust_svc>) should be 
 defined.  An FS::cust_svc record will be created and inserted.
 
+If an arrayref is passed as parameter, the B<jobnum>s of any export jobs will
+be added to the array.
+
 =cut
 
 sub insert {
   my $self = shift;
+  local $FS::queue::jobnums = shift if @_;
   my $error;
 
   local $SIG{HUP} = 'IGNORE';
@@ -359,7 +364,7 @@ sub cancel { ''; }
 
 =head1 VERSION
 
-$Id: svc_Common.pm,v 1.11 2002-06-11 03:25:03 ivan Exp $
+$Id: svc_Common.pm,v 1.12 2002-06-14 11:22:53 ivan Exp $
 
 =head1 BUGS
 
index aa089d0..9186e81 100644 (file)
@@ -8,6 +8,8 @@ use vars qw( @ISA $noexport_hack $conf
              $username_noperiod $username_nounderscore $username_nodash
              $username_uppercase
              $mydomain
+             $welcome_template $welcome_from $welcome_subject $welcome_mimetype
+             $smtpmachine
              $dirhash
              @saltset @pw_set );
 use Carp;
@@ -48,8 +50,19 @@ $FS::UID::callback{'FS::svc_acct'} = sub {
   $username_uppercase = $conf->exists('username-uppercase');
   $username_ampersand = $conf->exists('username-ampersand');
   $mydomain = $conf->config('domain');
-
   $dirhash = $conf->config('dirhash') || 0;
+  if ( $conf->exists('welcome_email') ) {
+    $welcome_template = new Text::Template (
+      TYPE   => 'ARRAY',
+      SOURCE => [ map "$_\n", $conf->config('welcome_email') ]
+    ) or warn "can't create welcome email template: $Text::Template::ERROR";
+    $welcome_from = $conf->config('welcome_email-from'); # || 'your-isp-is-dum'
+    $welcome_subject = $conf->config('welcome_email-subject') || 'Welcome';
+    $welcome_mimetype = $conf->config('welcome_email-mimetype') || 'text/plain';
+  } else {
+    $welcome_template = '';
+  }
+  $smtpmachine = $conf->config('smtpmachine');
 };
 
 @saltset = ( 'a'..'z' , 'A'..'Z' , '0'..'9' , '.' , '/' );
@@ -283,7 +296,8 @@ sub insert {
       && $self->username !~ /^toor$/ #FreeBSD
     ;
 
-  $error = $self->SUPER::insert;
+  my @jobnums;
+  $error = $self->SUPER::insert(\@jobnums);
   if ( $error ) {
     $dbh->rollback if $oldAutoCommit;
     return $error;
@@ -304,13 +318,58 @@ sub insert {
   }
 
   #false laziness with sub replace (and cust_main)
-  my $queue = new FS::queue { 'job' => 'FS::svc_acct::append_fuzzyfiles' };
+  my $queue = new FS::queue {
+    'svcnum' => $self->svcnum,
+    'job'    => 'FS::svc_acct::append_fuzzyfiles'
+  };
   $error = $queue->insert($self->username);
   if ( $error ) {
     $dbh->rollback if $oldAutoCommit;
     return "queueing job (transaction rolled back): $error";
   }
 
+  #welcome email
+  my $cust_pkg = $self->cust_svc->cust_pkg;
+  my( $cust_main, $to ) = ( '', '' );
+  if ( $welcome_template && $cust_pkg ) {
+    my $cust_main = $cust_pkg->cust_main;
+    my $to = join(', ', grep { $_ ne 'POST' } $cust_main->invoicing_list );
+    if ( $to ) {
+      my $wqueue = new FS::queue {
+        'svcnum' => $self->svcnum,
+        'job'    => 'FS::svc_acct::send_email'
+      };
+      warn "attempting to queue email to $to";
+      my $error = $wqueue->insert(
+        'to'       => $to,
+        'from'     => $welcome_from,
+        'subject'  => $welcome_subject,
+        'mimetype' => $welcome_mimetype,
+        'body'     => $welcome_template->fill_in( HASH => {
+                        'username' => $self->username,
+                        'password' => $self->_password,
+                        'first'    => $cust_main->first,
+                        'last'     => $cust_main->getfield('last'),
+                        'pkg'      => $cust_pkg->part_pkg->pkg,
+                      } ),
+      );
+      if ( $error ) {
+        $dbh->rollback if $oldAutoCommit;
+        return "queuing welcome email: $error";
+      }
+  
+      foreach my $jobnum ( @jobnums ) {
+        my $error = $wqueue->depend_insert($jobnum);
+        if ( $error ) {
+          $dbh->rollback if $oldAutoCommit;
+          return "queuing welcome email job dependancy: $error";
+        }
+      }
+
+    }
+  
+  }
+
   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
   ''; #no error
 }
@@ -487,7 +546,10 @@ sub replace {
   }
 
   #false laziness with sub insert (and cust_main)
-  my $queue = new FS::queue { 'job' => 'FS::svc_acct::append_fuzzyfiles' };
+  my $queue = new FS::queue {
+    'svcnum' => $new->svcnum,
+    'job'    => 'FS::svc_acct::append_fuzzyfiles'
+  };
   $error = $queue->insert($new->username);
   if ( $error ) {
     $dbh->rollback if $oldAutoCommit;
@@ -879,6 +941,40 @@ sub radius_groups {
 
 =over 4
 
+=item send_email
+
+=cut
+
+sub send_email {
+  my %opt = @_;
+
+  use Date::Format;
+  use Mail::Internet 1.44;
+  use Mail::Header;
+
+  $opt{mimetype} ||= 'text/plain';
+  $opt{mimetype} .= '; charset="iso-8859-1"' unless $opt{mimetype} =~ /charset/;
+
+  $ENV{MAILADDRESS} = $opt{from};
+  my $header = new Mail::Header ( [
+    "From: $opt{from}",
+    "To: $opt{to}",
+    "Sender: $opt{from}",
+    "Reply-To: $opt{from}",
+    "Date: ". time2str("%a, %d %b %Y %X %z", time),
+    "Subject: $opt{subject}",
+    "Content-Type: $opt{mimetype}",
+  ] );
+  my $message = new Mail::Internet (
+    'Header' => $header,
+    'Body' => [ map "$_\n", split("\n", $opt{body}) ],
+  );
+  $!=0;
+  $message->smtpsend( Host => $smtpmachine )
+    or $message->smtpsend( Host => $smtpmachine, Debug => 1 )
+      or die "can't send email to $opt{to} via $smtpmachine with SMTP: $!";
+}
+
 =item check_and_rebuild_fuzzyfiles
 
 =cut
index 67e5e2b..846055d 100644 (file)
@@ -61,44 +61,48 @@ while (1) {
   }
   $warnkids=0;
 
-  my $nodepend = driver name eq 'mysql'
+  my $nodepend = driver_name eq 'mysql'
    ? ''
    : 'AND 0 = ( SELECT COUNT(*) FROM queue_depend'.
      ' WHERE queue_depend.jobnum = queue.jobnum ) ';
 
-  my($job, $ljob);
-  {
-    my $oldAutoCommit = $FS::UID::AutoCommit;
-    local $FS::UID::AutoCommit = 0;
-    my $dbh = dbh; 
+  #my($job, $ljob);
+  #{
+  #  my $oldAutoCommit = $FS::UID::AutoCommit;
+  #  local $FS::UID::AutoCommit = 0;
+  $FS::UID::AutoCommit = 0;
+  my $dbh = dbh; 
   
-    $job = qsearchs(
-      'queue',
-      { 'status' => 'new' },
-      '',
-      driver_name eq 'mysql'
-        ? "$nodepend ORDER BY jobnum LIMIT 1 FOR UPDATE"
-        : "$nodepend ORDER BY jobnum FOR UPDATE LIMIT 1"
-    ) or do {
-      $dbh->commit or die $dbh->errstr if $oldAutoCommit;
-      sleep 5; #connecting to db is expensive
-      next;
-    };
-
-    if ( driver_name eq 'mysql'
-         && qsearch('queue_depend', { 'jobnum' => $job->jobnum } ) ) {
-      $dbh->commit or die $dbh->errstr if $oldAutoCommit;
-      next;
-    }
+  my $job = qsearchs(
+    'queue',
+    { 'status' => 'new' },
+    '',
+    driver_name eq 'mysql'
+      ? "$nodepend ORDER BY jobnum LIMIT 1 FOR UPDATE"
+      : "$nodepend ORDER BY jobnum FOR UPDATE LIMIT 1"
+  ) or do {
+    $dbh->commit or die $dbh->errstr; #if $oldAutoCommit;
+    sleep 5; #connecting to db is expensive
+    next;
+  };
 
-    my %hash = $job->hash;
-    $hash{'status'} = 'locked';
-    $ljob = new FS::queue ( \%hash );
-    my $error = $ljob->replace($job);
-    die $error if $error;
+  if ( driver_name eq 'mysql'
+       && qsearch('queue_depend', { 'jobnum' => $job->jobnum } ) ) {
+    $dbh->commit or die $dbh->errstr; #if $oldAutoCommit;
+    sleep 5; #would be better if mysql could do everything in query above
+    next;
+  }
+
+  my %hash = $job->hash;
+  $hash{'status'} = 'locked';
+  my $ljob = new FS::queue ( \%hash );
+  my $error = $ljob->replace($job);
+  die $error if $error;
+
+  $dbh->commit or die $dbh->errstr; #if $oldAutoCommit;
 
-    $dbh->commit or die $dbh->errstr if $oldAutoCommit;
-  } 
+  $FS::UID::AutoCommit = 1;
+  #
 
   my @args = $ljob->args;