add a new, extended CSV import format
authorivan <ivan>
Tue, 15 Aug 2006 14:20:51 +0000 (14:20 +0000)
committerivan <ivan>
Tue, 15 Aug 2006 14:20:51 +0000 (14:20 +0000)
FS/FS/cust_main.pm
httemplate/misc/cust_main-import.cgi
httemplate/misc/process/cust_main-import.cgi

index 95097da..c40d54a 100644 (file)
@@ -4230,9 +4230,33 @@ sub batch_import {
   #warn join('-',keys %$param);
   my $fh = $param->{filehandle};
   my $agentnum = $param->{agentnum};
+
   my $refnum = $param->{refnum};
   my $pkgpart = $param->{pkgpart};
-  my @fields = @{$param->{fields}};
+
+  #my @fields = @{$param->{fields}};
+  my $format = $param->{'format'};
+  my @fields;
+  my $payby;
+  if ( $format eq 'simple' ) {
+    @fields = qw( cust_pkg.setup dayphone first last
+                  address1 address2 city state zip comments );
+    $payby = 'BILL';
+  } elsif ( $format eq 'extended' ) {
+    @fields = qw( agent_custid refnum
+                  last first address1 address2 city state zip country
+                  daytime night
+                  ship_last ship_first ship_address1 ship_address2
+                  ship_city ship_state ship_zip ship_country
+                  payinfo paycvv paydate
+                  invoicing_list
+                  cust_pkg.pkgpart
+                  svc_acct.username svc_acct._password 
+                );
+    $payby = 'CARD';
+  } else {
+    die "unknown format $format";
+  }
 
   eval "use Text::CSV_XS;";
   die $@ if $@;
@@ -4271,51 +4295,99 @@ sub batch_import {
       agentnum => $agentnum,
       refnum   => $refnum,
       country  => $conf->config('countrydefault') || 'US',
-      payby    => 'BILL', #default
+      payby    => $payby, #default
       paydate  => '12/2037', #default
     );
     my $billtime = time;
     my %cust_pkg = ( pkgpart => $pkgpart );
+    my %svc_acct = ();
     foreach my $field ( @fields ) {
-      if ( $field =~ /^cust_pkg\.(setup|bill|susp|expire|cancel)$/ ) {
+
+      if ( $field =~ /^cust_pkg\.(pkgpart|setup|bill|susp|expire|cancel)$/ ) {
+
         #$cust_pkg{$1} = str2time( shift @$columns );
-        if ( $1 eq 'setup' ) {
+        if ( $1 eq 'pkgpart' ) {
+          $cust_pkg{$1} = shift @columns;
+        } elsif ( $1 eq 'setup' ) {
           $billtime = str2time(shift @columns);
         } else {
           $cust_pkg{$1} = str2time( shift @columns );
-        }
+        } 
+
+      } elsif ( $field =~ /^svc_acct\.(username|_password)$/ ) {
+
+        $svc_acct{$1} = shift @columns;
+        
       } else {
+
+        #refnum interception
+        if ( $field eq 'refnum' && $columns[0] !~ /^\s*(\d+)\s*$/ ) {
+
+          my $referral = $columns[0];
+          my $part_referral = new FS::part_referral {
+            'referral' => $referral,
+            'agentnum' => $agentnum,
+          };
+
+          my $error = $part_referral->insert;
+          if ( $error ) {
+            $dbh->rollback if $oldAutoCommit;
+            return "can't auto-insert advertising source: $referral: $error";
+          }
+          $columns[0] = $part_referral->refnum;
+        }
+
         #$cust_main{$field} = shift @$columns; 
         $cust_main{$field} = shift @columns; 
       }
     }
 
-    my $cust_pkg = new FS::cust_pkg ( \%cust_pkg ) if $pkgpart;
+    my $invoicing_list = $cust_main{'invoicing_list'}
+                           ? [ delete $cust_main{'invoicing_list'} ]
+                           : [];
+
     my $cust_main = new FS::cust_main ( \%cust_main );
+
     use Tie::RefHash;
     tie my %hash, 'Tie::RefHash'; #this part is important
-    $hash{$cust_pkg} = [] if $pkgpart;
-    my $error = $cust_main->insert( \%hash );
 
-    if ( $error ) {
-      $dbh->rollback if $oldAutoCommit;
-      return "can't insert customer for $line: $error";
+    if ( $cust_pkg{'pkgpart'} ) {
+      my $cust_pkg = new FS::cust_pkg ( \%cust_pkg );
+
+      my @svc_acct = ();
+      if ( $svc_acct{'username'} ) {
+        $svc_acct{svcpart} = $cust_pkg->part_pkg->svcpart( 'svc_acct' );
+        push @svc_acct, new FS::svc_acct ( \%svc_acct )
+      }
+
+      $hash{$cust_pkg} = \@svc_acct;
     }
 
-    #false laziness w/bill.cgi
-    $error = $cust_main->bill( 'time' => $billtime );
+    my $error = $cust_main->insert( \%hash, $invoicing_list );
+
     if ( $error ) {
       $dbh->rollback if $oldAutoCommit;
-      return "can't bill customer for $line: $error";
+      return "can't insert customer for $line: $error";
     }
 
-    $cust_main->apply_payments;
-    $cust_main->apply_credits;
+    if ( $format eq 'simple' ) {
+
+      #false laziness w/bill.cgi
+      $error = $cust_main->bill( 'time' => $billtime );
+      if ( $error ) {
+        $dbh->rollback if $oldAutoCommit;
+        return "can't bill customer for $line: $error";
+      }
+  
+      $cust_main->apply_payments;
+      $cust_main->apply_credits;
+  
+      $error = $cust_main->collect();
+      if ( $error ) {
+        $dbh->rollback if $oldAutoCommit;
+        return "can't collect customer for $line: $error";
+      }
 
-    $error = $cust_main->collect();
-    if ( $error ) {
-      $dbh->rollback if $oldAutoCommit;
-      return "can't collect customer for $line: $error";
     }
 
     $imported++;
index 4848550..2ad4d95 100644 (file)
@@ -1,51 +1,65 @@
-<!-- mason kludge -->
 <%= include("/elements/header.html",'Batch Customer Import') %>
+
 <FORM ACTION="process/cust_main-import.cgi" METHOD="post" ENCTYPE="multipart/form-data">
-Import a CSV file containing customer records.<BR><BR>
-Default file format is CSV, with the following field order: <i>cust_pkg.setup, dayphone, first, last, address1, address2, city, state, zip, comments</i><BR><BR>
 
-<%
-  #false laziness with edit/cust_main.cgi
-  my @agents = qsearch( 'agent', {} );
-  die "No agents created!" unless @agents;
-  my $agentnum = $agents[0]->agentnum; #default to first
+Import a CSV file containing customer records.
+<BR><BR>
+
+<!-- Simple file format is CSV, with the following field order: <i>cust_pkg.setup, dayphone, first, last, address1, address2, city, state, zip, comments</i>
+<BR><BR> -->
+
+Extended file format is CSV, with the following field order: <i>agent_custid, refnum[1], last, first, address1, address2, city, state, zip, country, daytime, night, ship_last, ship_first, ship_address1, ship_address2, ship_city, ship_state, ship_zip, ship_country, payinfo, paycvv, paydate, invoicing_list, pkgpart, username, _password</i>
+<BR><BR>
 
-  if ( scalar(@agents) == 1 ) {
+[1] This field has special treatment upon import: If a string is passed instead
+of an integer, the string is searched for and if necessary auto-created in the
+target table.
+<BR><BR>
+
+<%= &ntable("#cccccc") %>
+
+<%= include('/elements/tr-select-agent.html', '', #$agentnum,
+              'label'       => "<B>Agent</B>",
+              'empty_label' => 'Select agent',
+           )
 %>
-    <INPUT TYPE="hidden" NAME="agentnum" VALUE="<%= $agentnum %>">
-<% } else { %>
-    <BR><BR>Agent <SELECT NAME="agentnum" SIZE="1">
-  <% foreach my $agent (sort { $a->agent cmp $b->agent } @agents) { %>
-    <OPTION VALUE="<%= $agent->agentnum %>" <%= " SELECTED"x($agent->agentnum==$agentnum) %>><%= $agent->agent %></OPTION>
-  <% } %>
-    </SELECT><BR><BR>
-<% } %>
-
-<%
-  my @referrals = qsearch('part_referral',{});
-  die "No advertising sources created!" unless @referrals;
-  my $refnum = $referrals[0]->refnum; #default to first
-
-  if ( scalar(@referrals) == 1 ) {
+
+<TR>
+  <TH ALIGN="right">Format</TH>
+  <TD>
+    <SELECT NAME="format">
+<!--      <OPTION VALUE="simple">Simple -->
+      <OPTION VALUE="extended" SELECTED>Extended
+    </SELECT>
+  </TD>
+</TR>
+
+<TR>
+  <TH ALIGN="right">CSV filename</TH>
+  <TD><INPUT TYPE="file" NAME="csvfile"></TD>
+</TR>
+
+<% #include('/elements/tr-select-part_referral.html')
 %>
-    <INPUT TYPE="hidden" NAME="refnum" VALUE="<%= $refnum %>">
-<% } else { %>
-    <BR><BR>Advertising source <SELECT NAME="refnum" SIZE="1">
-  <% foreach my $referral ( sort { $a->referral <=> $b->referral } @referrals) { %>
-    <OPTION VALUE="<%= $referral->refnum %>" <%= " SELECTED"x($referral->refnum==$refnum) %>><%= $referral->refnum %>: <%= $referral->referral %></OPTION>
-  <% } %>
-    </SELECT><BR><BR>
-<% } %>
-
-    First package: <SELECT NAME="pkgpart"><OPTION VALUE="">(none)</OPTION>
-<% foreach my $part_pkg ( qsearch('part_pkg',{'disabled'=>'' }) ) { %>
-     <OPTION VALUE="<%= $part_pkg->pkgpart %>"><%= $part_pkg->pkg. ' - '. $part_pkg->comment %></OPTION>
-<% } %>
-</SELECT><BR><BR>
-
-    CSV Filename: <INPUT TYPE="file" NAME="csvfile"><BR><BR>
-    <INPUT TYPE="submit" VALUE="Import">
-    </FORM>
-  </BODY>
-<HTML>
+
+<!--
+<TR>
+  <TH>First package</TH>
+  <TD>
+    <SELECT NAME="pkgpart"><OPTION VALUE="">(none)</OPTION>
+      <% foreach my $part_pkg ( qsearch('part_pkg',{'disabled'=>'' }) ) { %>
+       <OPTION VALUE="<%= $part_pkg->pkgpart %>"><%= $part_pkg->pkg. ' - '. $part_pkg->comment %></OPTION>
+      <% } %>
+    </SELECT>
+  </TD>
+</TR>
+-->
+
+</TABLE>
+<BR><BR>
+
+<INPUT TYPE="submit" VALUE="Import">
+</FORM>
+
+<%= include('/elements/footer.html') %>
 
index 371929a..aff6b39 100644 (file)
@@ -10,8 +10,9 @@
         agentnum   => scalar($cgi->param('agentnum')),
         refnum     => scalar($cgi->param('refnum')),
         pkgpart    => scalar($cgi->param('pkgpart')),
-        'fields'    => [qw( cust_pkg.setup dayphone first last address1 address2
-                           city state zip comments                          )],
+        #'fields'    => [qw( cust_pkg.setup dayphone first last address1 address2
+        #                   city state zip comments                          )],
+        'format'   => scalar($cgi->param('format')),
       } )
     : 'No file';