merging is now attaching by default, with the old destructive merge operation as...
authorIvan Kohler <ivan@freeside.biz>
Fri, 3 May 2013 07:31:07 +0000 (00:31 -0700)
committerIvan Kohler <ivan@freeside.biz>
Fri, 3 May 2013 07:31:07 +0000 (00:31 -0700)
FS/FS/cust_main/Packages.pm
FS/FS/cust_pkg.pm
httemplate/misc/cust_main-merge.html
httemplate/misc/merge_cust.html
httemplate/view/cust_main.cgi

index f83bce9..e904cfd 100644 (file)
@@ -4,7 +4,7 @@ use strict;
 use vars qw( $DEBUG $me );
 use List::Util qw( min );
 use FS::UID qw( dbh );
-use FS::Record qw( qsearch );
+use FS::Record qw( qsearch qsearchs );
 use FS::cust_pkg;
 use FS::cust_svc;
 
@@ -291,6 +291,80 @@ sub order_pkgs {
   ''; #no error
 }
 
+=item attach_pkgs 
+
+Merges this customer's package's into the target customer and then cancels them.
+
+=cut
+
+sub attach_pkgs {
+  my( $self, $new_custnum ) = @_;
+
+  #mostly false laziness w/ merge
+
+  return "Can't attach packages to self" if $self->custnum == $new_custnum;
+
+  my $new_cust_main = qsearchs( 'cust_main', { 'custnum' => $new_custnum } )
+    or return "Invalid new customer number: $new_custnum";
+
+  return 'Access denied: "Merge customer across agents" access right required to merge into a customer of a different agent'
+    if $self->agentnum != $new_cust_main->agentnum 
+    && ! $FS::CurrentUser::CurrentUser->access_right('Merge customer across agents');
+
+  local $SIG{HUP} = 'IGNORE';
+  local $SIG{INT} = 'IGNORE';
+  local $SIG{QUIT} = 'IGNORE';
+  local $SIG{TERM} = 'IGNORE';
+  local $SIG{TSTP} = 'IGNORE';
+  local $SIG{PIPE} = 'IGNORE';
+
+  my $oldAutoCommit = $FS::UID::AutoCommit;
+  local $FS::UID::AutoCommit = 0;
+  my $dbh = dbh;
+
+  if ( qsearch('agent', { 'agent_custnum' => $self->custnum } ) ) {
+     $dbh->rollback if $oldAutoCommit;
+     return "Can't merge a master agent customer";
+  }
+
+  #use FS::access_user
+  if ( qsearch('access_user', { 'user_custnum' => $self->custnum } ) ) {
+     $dbh->rollback if $oldAutoCommit;
+     return "Can't merge a master employee customer";
+  }
+
+  if ( qsearch('cust_pay_pending', { 'custnum' => $self->custnum,
+                                     'status'  => { op=>'!=', value=>'done' },
+                                   }
+              )
+  ) {
+     $dbh->rollback if $oldAutoCommit;
+     return "Can't merge a customer with pending payments";
+  }
+
+  #end of false laziness
+
+  foreach my $cust_pkg ( $self->ncancelled_pkgs ) {
+
+    my $pkg_or_error = $cust_pkg->change( {
+      'keep_dates' => 1,
+      'cust_main'  => $new_cust_main,
+    } );
+
+    my $error = ref($pkg_or_error) ? '' : $pkg_or_error;
+
+    if ( $error ) {
+      $dbh->rollback if $oldAutoCommit;
+      return $error;
+    }
+
+  }
+
+  $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+  ''; #no error
+
+}
+
 =item all_pkgs [ OPTION => VALUE... | EXTRA_QSEARCH_PARAMS_HASHREF ]
 
 Returns all packages (see L<FS::cust_pkg>) for this customer.
index d8b6e69..df5a4dc 100644 (file)
@@ -1827,7 +1827,7 @@ sub change {
   my $custnum = $self->custnum;
   if ( $opt->{cust_main} ) {
     my $cust_main = $opt->{cust_main};
-    unless ( $cust_main->custnum) { 
+    unless ( $cust_main->custnum ) { 
       my $error = $cust_main->insert;
       if ( $error ) {
         $dbh->rollback if $oldAutoCommit;
index 4decbef..3b4425f 100755 (executable)
@@ -31,7 +31,17 @@ if ( $cgi->param('new_custnum') =~ /^(\d+)$/ ) {
   } );
   die "No customer # $custnum" unless $cust_main;
 
-  $error = $cust_main->merge($new_custnum);
+  if ( $cgi->param('merge') eq 'Y' ) {
+
+    #old-style merge: everything + delete old customer
+    $error = $cust_main->merge($new_custnum);
+
+  } else {
+
+    #new-style attach: move packages 3.0 style, that's it
+    $error = $cust_main->attach_pkgs($new_custnum);
+
+  }
 
 } else {
   $error = 'Select a customer to merge into';
index ad075be..9c869fa 100644 (file)
@@ -1,6 +1,6 @@
-<% include('/elements/header-popup.html', 'Merge customer' ) %>
+<& /elements/header-popup.html, 'Merge customer' &>
 
-<% include('/elements/error.html') %>
+<& /elements/error.html &>
 
 <FORM NAME="cust_merge_popup" ID="cust_merge_popup" ACTION="<% popurl(1) %>cust_main-merge.html" METHOD=POST onSubmit="submit_merge(); return false;">
 
@@ -35,13 +35,43 @@ function do_submit_merge() {
 <INPUT TYPE="hidden" NAME="custnum" VALUE="<% $custnum %>">
 
 <TABLE BORDER="0" CELLSPACING="2" STYLE="margin-left:auto; margin-right:auto">
-  <% include('/elements/tr-search-cust_main.html',
+
+  <& /elements/tr-search-cust_main.html,
                'label'       => 'Merge into: ',
                'field'       => 'new_custnum',
                'find_button' => 1,
                'curr_value'  => scalar($cgi->param('new_custnum')),
-            )
-  %>
+  &>
+
+% if ( $conf->exists('deletecustomers') ) {
+
+%   if ( scalar($cust_main->ncancelled_pkgs) ) {
+      <TR>
+        <TD COLSPAN=2>
+          <& /elements/radio.html,
+               'field'       => 'merge',
+               'value'       => '',
+               'curr_value'  => scalar($cgi->param('merge')),
+          &>
+          Merge packages only.
+        </TD>
+      </TR>
+%   } else {
+%     $cgi->param('merge', 'Y');
+%   }
+
+    <TR>
+      <TD COLSPAN=2>
+        <& /elements/radio.html,
+             'field'       => 'merge',
+             'value'       => 'Y',
+             'curr_value'  => scalar($cgi->param('merge')),
+        &>
+        Merge invoices, payments/credits, notes, tickets and delete this customer.
+      </TD>
+    </TR>
+% }
+
 </TABLE>
 
 <P ALIGN="CENTER">
@@ -54,6 +84,8 @@ function do_submit_merge() {
 
 <%init>
 
+my $conf = new FS::Conf;
+
 $cgi->param('custnum') =~ /^(\d+)$/ or die 'illegal custnum';
 my $custnum = $1;
 
index ec31919..be0100f 100755 (executable)
@@ -91,14 +91,19 @@ function areyousure(href, message) {
   &> | 
 % }
 
-% if ( $curuser->access_right('Merge customer') ) {
+% if (     $curuser->access_right('Merge customer')
+%      and (    scalar($cust_main->ncancelled_pkgs)
+%            || $conf->exists('deletecustomers')
+%          )
+%    )
+% {
   <& /elements/popup_link-cust_main.html,
               { 'action'      => $p. 'misc/merge_cust.html',
                 'label'       => emt('Merge this customer'),
                 'actionlabel' => emt('Merge customer'),
                 'cust_main'   => $cust_main,
-                'width'       => 480,
-                'height'      => 192,
+                'width'       => 569,
+                'height'      => 210,
               }
   &> | 
 % }