%
my $conf = new FS::Conf;
my %uiview = ();
my %uiadd = ();
foreach my $part_svc ( qsearch('part_svc',{}) ) {
  $uiview{$part_svc->svcpart} = popurl(2). "view/". $part_svc->svcdb . ".cgi";
  $uiadd{$part_svc->svcpart}= popurl(2). "edit/". $part_svc->svcdb . ".cgi";
}
print header("Customer View", menubar(
  'Main Menu' => popurl(2)
));
%>
<%
die "No customer specified (bad URL)!" unless $cgi->keywords;
my($query) = $cgi->keywords; # needs parens with my, ->keywords returns array
$query =~ /^(\d+)$/;
my $custnum = $1;
my $cust_main = qsearchs('cust_main',{'custnum'=>$custnum});
die "Customer not found!" unless $cust_main;
print qq!Edit this customer!;
%>
<%
print qq! | !.
      'Cancel this customer'
  if $cust_main->ncancelled_pkgs;
print qq! | !.
      'Delete this customer'
  if $conf->exists('deletecustomers');
unless ( $conf->exists('disable_customer_referrals') ) {
  print qq! | !,
        qq!Refer a new customer!;
  print qq! | !,
        qq!View this customer's referrals!;
}
print '
';
my $signupurl = $conf->config('signupurl');
if ( $signupurl ) {
print "This customer's signup URL: ".
      "$signupurl?ref=$custnum
";
}
print '';
print &itable(), '
';
print '| ';
  print "Billing address", &ntable("#cccccc"), " | 
| ",
        &ntable("#cccccc",2),
    ' | 
| Contact name',
      ' | ',
      $cust_main->last, ', ', $cust_main->first,
      '';
print ' | SS# | ',
      $cust_main->ss || ' ', ''
  if $conf->exists('show_ss');
print ' | 
',
    '| Company | ',
      $cust_main->company,
      ' | 
',
    '| Address | ',
      $cust_main->address1,
      ' | 
',
  ;
  print '|  | ',
        $cust_main->address2, ' | 
'
    if $cust_main->address2;
  print '| City | ',
          $cust_main->city,
          ' | State | ',
          $cust_main->state,
          ' | Zip | ',
          $cust_main->zip, ' | 
',
        '| Country | ',
          $cust_main->country,
          ' | 
',
  ;
  my $daytime_label = FS::Msgcat::_gettext('daytime') || 'Day Phone';
  my $night_label = FS::Msgcat::_gettext('night') || 'Night Phone';
  print '| '. $daytime_label.
          ' | ',
          $cust_main->daytime || ' ', ' | 
',
        '| '. $night_label. 
          ' | ',
          $cust_main->night || ' ', ' | 
',
        '| Fax | ',
          $cust_main->fax || ' ', ' | 
',
        '', ""
  ;
  if ( defined $cust_main->dbdef_table->column('ship_last') ) {
    my $pre = $cust_main->ship_last ? 'ship_' : '';
    print "
Service address", &ntable("#cccccc"), "| ",
          &ntable("#cccccc",2),
      ' | 
| Contact name',
        ' | ',
        $cust_main->get("${pre}last"), ', ', $cust_main->get("${pre}first"),
        ' | 
',
      '| Company | ',
        $cust_main->get("${pre}company"),
        ' | 
',
      '| Address | ',
        $cust_main->get("${pre}address1"),
        ' | 
',
    ;
    print '|  | ',
          $cust_main->get("${pre}address2"), ' | 
'
      if $cust_main->get("${pre}address2");
    print '| City | ',
            $cust_main->get("${pre}city"),
            ' | State | ',
            $cust_main->get("${pre}state"),
            ' | Zip | ',
            $cust_main->get("${pre}zip"), ' | 
',
          '| Country | ',
            $cust_main->get("${pre}country"),
            ' | 
',
    ;
    print '| '. $daytime_label. '',
          ' | ',
            $cust_main->get("${pre}daytime") || ' ', ' | 
',
          '| '. $night_label. ''.
          ' | ',
            $cust_main->get("${pre}night") || ' ', ' | 
',
          '| Fax | ',
            $cust_main->get("${pre}fax") || ' ', ' | 
',
          '', ""
    ;
  }
print '';
print '';
  print &ntable("#cccccc"), " | | ", &ntable("#cccccc",2),
        ' | 
| Customer number | ',
        $custnum, ' | 
',
  ;
  my @agents = qsearch( 'agent', {} );
  my $agent;
  unless ( scalar(@agents) == 1 ) {
    $agent = qsearchs('agent',{ 'agentnum' => $cust_main->agentnum } );
    print '| Agent | ',
        $agent->agentnum, ": ", $agent->agent, ' | 
';
  } else {
    $agent = $agents[0];
  }
  my @referrals = qsearch( 'part_referral', {} );
  unless ( scalar(@referrals) == 1 ) {
    my $referral = qsearchs('part_referral', {
      'refnum' => $cust_main->refnum
    } );
    print '| Advertising source | ',
          $referral->refnum, ": ", $referral->referral, ' | 
';
  }
  print '| Order taker | ',
    $cust_main->otaker, ' | 
';
  print '| Referring Customer | ';
  my $referring_cust_main = '';
  if ( $cust_main->referral_custnum
       && ( $referring_cust_main =
            qsearchs('cust_main', { custnum => $cust_main->referral_custnum } )
          )
     ) {
    print ''.
          $cust_main->referral_custnum. ': '.
          ( $referring_cust_main->company
              ? $referring_cust_main->company. ' ('.
                  $referring_cust_main->last. ', '. $referring_cust_main->first.
                  ')'
              : $referring_cust_main->last. ', '. $referring_cust_main->first
          ).
          '';
  }
  print ' | 
';
  print '';
print '
';
if ( $conf->config('payby-default') ne 'HIDE' ) {
  my @invoicing_list = $cust_main->invoicing_list;
  print "Billing information (",
       qq!!, "Bill now)",
        &ntable("#cccccc"), "| ", &ntable("#cccccc",2),
        ' | 
| Tax exempt | ',
        $cust_main->tax ? 'yes' : 'no',
        ' | 
',
        '| Postal invoices | ',
        ( grep { $_ eq 'POST' } @invoicing_list ) ? 'yes' : 'no',
        ' | 
',
        '| Email invoices | ',
        join(', ', grep { $_ ne 'POST' } @invoicing_list ) || 'no',
        ' | 
',
        '| Billing type | ',
  ;
  if ( $cust_main->payby eq 'CARD' || $cust_main->payby eq 'DCRD' ) {
    my $payinfo = $cust_main->payinfo_masked;
    print 'Credit card ',
          ( $cust_main->payby eq 'CARD' ? '(automatic)' : '(on-demand)' ),
          ' | 
',
          '| Card number | ',
          $payinfo, ' | 
',
          '| Expiration | ',
          $cust_main->paydate, ' | 
',
          '| Name on card | ',
          $cust_main->payname, ' | 
'
    ;
  } elsif ( $cust_main->payby eq 'CHEK' || $cust_main->payby eq 'DCHK') {
    my( $account, $aba ) = split('@', $cust_main->payinfo );
    print 'Electronic check ',
          ( $cust_main->payby eq 'CHEK' ? '(automatic)' : '(on-demand)' ),
          '',
          '| Account number | ',
          $account, ' | 
',
          '| ABA/Routing code | ',
          $aba, ' | 
',
          '| Bank name | ',
          $cust_main->payname, ' | 
'
    ;
  } elsif ( $cust_main->payby eq 'LECB' ) {
    $cust_main->payinfo =~ /^(\d{3})(\d{3})(\d{4})$/;
    my $payinfo = "$1-$2-$3";
    print 'Phone bill billing',
          '| Phone number | ',
          $payinfo, ' | 
',
    ;
  } elsif ( $cust_main->payby eq 'BILL' ) {
    print 'Billing';
    print '| P.O. | ',
          $cust_main->payinfo, ' | 
',
      if $cust_main->payinfo;
    print '| Expiration | ',
          $cust_main->paydate, ' | 
',
          '| Attention | ',
          $cust_main->payname, ' | 
',
    ;
  } elsif ( $cust_main->payby eq 'COMP' ) {
    print 'Complimentary',
          '| Authorized by | ',
          $cust_main->payinfo, ' | 
',
          '| Expiration | ',
          $cust_main->paydate, ' | 
',
    ;
  }
  print "";
}
print '';
if ( defined $cust_main->dbdef_table->column('comments')
     && $cust_main->comments =~ /[^\s\n\r]/ )
{
  print "
Comments". &ntable("#cccccc"). "| ".
        &ntable("#cccccc",2).
        ' | 
| '.
        encode_entities($cust_main->comments).
        ' | 
';
}
%>
<%
if ( $conf->config('payby-default') ne 'HIDE' ) {
  print
    qq!
!;
}
print qq!Packages !,
      qq!( Order and cancel packages (preserves services) )!,
;
#begin display packages
#get package info
my $packages = get_packages($cust_main, $conf);
if ( @$packages ) {
%>
  | Package | Status | Services | 
<%
foreach my $pkg (sort pkgsort_pkgnum_cancel @$packages) {
  my $rowspan = 0;
  if ($pkg->{cancel}) {
    $rowspan = 0;
  } else {
    foreach my $svcpart (@{$pkg->{svcparts}}) {
      $rowspan += $svcpart->{count};
      $rowspan++ if ($svcpart->{count} < $svcpart->{quantity});
    }
  } 
%>
  | >
    <%=$pkg->{pkgnum}%>:
    <%=$pkg->{pkg}%> - <%=$pkg->{comment}%> <%
  #foreach (qw(setup last_bill next_bill susp expire cancel)) {
  #  print qq!<% unless ($pkg->{cancel}) { %>
    ( <%=pkg_change_link($pkg)%> )
    ( <%=pkg_dates_link($pkg)%> | <%=pkg_customize_link($pkg,$custnum)%> )
<% } %>
 | ! . pkg_datestr($pkg,$_,$conf) . qq!\n!;
  #}
  print " | ". &itable('');
  sub myfreq {
    my $part_pkg = shift;
    my $freq = $part_pkg->freq_pretty;
    $freq =~ s/ / /g;
    $freq;
  }
  if ( $pkg->{cancel} ) { #status: cancelled
    print ' | 
| Cancelled'.
          ' | '. pkg_datestr($pkg,'cancel',$conf). ' | 
';
    unless ( $pkg->{setup} ) {
      print '| Never billed | 
';
    } else {
      print "| Setup | ".
            pkg_datestr($pkg, 'setup',$conf). ' | 
';
      print "| Last bill | ".
            pkg_datestr($pkg, 'last_bill',$conf). ' | 
'
        if $pkg->{'last_bill'};
      print "| Suspended | ".
            pkg_datestr($pkg, 'susp',$conf). ' | 
'
        if $pkg->{'susp'};
    }
  } else {
    if ( $pkg->{susp} ) { #status: suspended
      print '| Suspended'.
            ' | '. pkg_datestr($pkg,'susp',$conf). ' | 
';
      unless ( $pkg->{setup} ) {
        print '| Never billed | 
';
      } else {
        print "| Setup | ". 
              pkg_datestr($pkg, 'setup',$conf). ' | 
';
      }
      print "| Last bill | ".
            pkg_datestr($pkg, 'last_bill',$conf). ' | 
'
        if $pkg->{'last_bill'};
      # next bill ??
      print "| Expires | ".
            pkg_datestr($pkg, 'expire',$conf). ' | 
'
        if $pkg->{'expire'};
      print '| ( '. pkg_unsuspend_link($pkg).
            ' | '. pkg_cancel_link($pkg). ' ) | 
';
    } else { #status: active
      unless ( $pkg->{setup} ) { #not setup
        print '| Not yet billed (';
        unless ( $pkg->{freq} ) {
          print 'one-time charge) | 
';
          print '| ( '. pkg_cancel_link($pkg).
                ' )';
        } else {
          print 'billed '. myfreq($pkg->{part_pkg}). ') | 
';
        }
      } else { #setup
        unless ( $pkg->{freq} ) {
          print "| One-time charge | 
".
                '| Billed | '.
                pkg_datestr($pkg,'setup',$conf). ' | 
';
        } else {
          print '| Active'.
                ', billed '. myfreq($pkg->{part_pkg}). ' | 
'.
                '| Setup | '.
                pkg_datestr($pkg, 'setup',$conf). ' | 
';
        }
      }
      print "| Last bill | ".
            pkg_datestr($pkg, 'last_bill',$conf). ' | 
'
        if $pkg->{'last_bill'};
      print "| Next bill | ".
            pkg_datestr($pkg, 'next_bill',$conf). ' | 
'
        if $pkg->{'next_bill'};
      print "| Expires | ".
            pkg_datestr($pkg, 'expire',$conf). ' | 
'
        if $pkg->{'expire'};
      if ( $pkg->{freq} ) {
        print '| ( '. pkg_suspend_link($pkg).
              ' | '. pkg_cancel_link($pkg). ' ) | 
';
      }
    }
  }
  print "
\n";
  if ($rowspan == 0) { print qq!\n!; next; }
  my $cnt = 0;
  foreach my $svcpart (sort {$a->{svcpart} <=> $b->{svcpart}} @{$pkg->{svcparts}}) {
    foreach my $service (@{$svcpart->{services}}) {
      print '' if ($cnt > 0);
%>
  | <%=svc_link($svcpart,$service)%> | <%=svc_label_link($svcpart,$service)%> ( <%=svc_unprovision_link($service)%> )
 | 
<%
      $cnt++;
    }
    if ($svcpart->{count} < $svcpart->{quantity}) {
      print qq!\n! if ($cnt > 0);
      print qq!  | !.svc_provision_link($pkg, $svcpart, $conf).qq!\n | 
\n!;
    }
  }
}
print '';
}
#end display packages
%>
<% if ( $conf->config('payby-default') ne 'HIDE' ) { %>
  
  
Payment History
  Post cash/check payment
  | Process credit card payment
  | Process electronic check (ACH) payment
  
Post credit
  
  <%
  #get payment history
  my @history = ();
  #invoices
  foreach my $cust_bill ($cust_main->cust_bill) {
    my $pre = ( $cust_bill->owed > 0 )
                ? 'Open '
                : '';
    my $post = ( $cust_bill->owed > 0 ) ? '' : '';
    my $invnum = $cust_bill->invnum;
    push @history, {
      'date'   => $cust_bill->_date,
      'desc'   => qq!!. $pre.
                  "Invoice #$invnum (Balance \$". $cust_bill->owed. ')'.
                  $post. '',
      'charge' => $cust_bill->charged,
    };
  }
  #payments (some false laziness w/credits)
  foreach my $cust_pay ($cust_main->cust_pay) {
    my $payby = $cust_pay->payby;
    my $payinfo = $payby eq 'CARD'
                    ? $cust_pay->payinfo_masked
                    : $cust_pay->payinfo;
    my @cust_bill_pay = $cust_pay->cust_bill_pay;
    my @cust_pay_refund = $cust_pay->cust_pay_refund;
    my $target = "$payby$payinfo";
    $payby =~ s/^BILL$/Check #/ if $payinfo;
    $payby =~ s/^CHEK$/Electronic check /;
    $payby =~ s/^BILL$//;
    $payby =~ s/^(CARD|COMP)$/$1 /;
    my $info = $payby ? " ($payby$payinfo)" : '';
    my( $pre, $post, $desc, $apply, $ext ) = ( '', '', '', '', '' );
    if (    scalar(@cust_bill_pay)   == 0
         && scalar(@cust_pay_refund) == 0 ) {
      #completely unapplied
      $pre = 'Unapplied ';
      $post = '';
      $apply = qq! (apply)';
    } elsif (    scalar(@cust_bill_pay)   == 1
              && scalar(@cust_pay_refund) == 0
              && $cust_pay->unapplied == 0     ) {
      #applied to one invoice, the usual situation
      $desc = ' applied to Invoice #'. $cust_bill_pay[0]->invnum;
    } elsif (    scalar(@cust_bill_pay)   == 0
              && scalar(@cust_pay_refund) == 1
              && $cust_pay->unapplied == 0     ) {
      #applied to one refund
      $desc = ' refunded on '. time2str("%D", $cust_pay_refund[0]->_date);
    } else {
      #complicated
      $desc = '
';
      foreach my $app ( sort { $a->_date <=> $b->_date }
                             ( @cust_bill_pay, @cust_pay_refund ) ) {
        if ( $app->isa('FS::cust_bill_pay') ) {
          $desc .= '  '.
                   '$'. $app->amount.
                   ' applied to Invoice #'. $app->invnum.
                   '
';
                   #' on '. time2str("%D", $cust_bill_pay->_date).
        } elsif ( $app->isa('FS::cust_pay_refund') ) {
          $desc .= '  '.
                   '$'. $app->amount.
                   ' refunded on'. time2str("%D", $app->_date).
                   '
';
        } else {
          die "$app is not a FS::cust_bill_pay or FS::cust_pay_refund";
        }
      }
      if ( $cust_pay->unapplied > 0 ) {
        $desc .= '  '.
                 '$'.
                 $cust_pay->unapplied. ' unapplied'.
                 qq! (apply)'.
                 '
';
      }
    }
    my $refund = '';
    my $refund_days = $conf->config('card_refund-days') || 120;
    if (    $cust_pay->closed !~ /^Y/i
         && $cust_pay->payby =~ /^(CARD|CHEK)$/
         && time-$cust_pay->_date < $refund_days*86400
         && $cust_pay->unrefunded > 0
    ) {
      $refund = qq! (refund)!;
    }
    my $void = '';
    if (    $cust_pay->closed !~ /^Y/i
         && $cust_pay->payby !~  /^(CARD|CHEK)$/
       ) {
      $void = qq! (!.
              qq!void)!;
    }
    my $delete = '';
    if ( $cust_pay->closed !~ /^Y/i && $conf->exists('deletepayments') ) {
      $delete = qq! (!.
                qq!delete)!;
    }
    my $unapply = '';
    if (    $cust_pay->closed !~ /^Y/i
         && $conf->exists('unapplypayments')
         && scalar(@cust_bill_pay)           ) {
      $unapply = qq! (!.
                 qq!unapply)!;
    }
    push @history, {
      'date'    => $cust_pay->_date,
      'desc'    => $pre. "Payment$post$info$desc".
                   "$apply$refund$void$delete$unapply",
      'payment' => $cust_pay->paid,
      'target'  => $target,
    };
  }
  #voided payments
  foreach my $cust_pay_void ($cust_main->cust_pay_void) {
    my $payby = $cust_pay_void->payby;
    my $payinfo = $payby eq 'CARD'
                    ? $cust_pay_void->payinfo_masked
                    : $cust_pay_void->payinfo;
    $payby =~ s/^BILL$/Check #/ if $payinfo;
    $payby =~ s/^CHEK$/Electronic check /;
    $payby =~ s/^BILL$//;
    $payby =~ s/^(CARD|COMP)$/$1 /;
    my $info = $payby ? " ($payby$payinfo)" : '';
    push @history, {
      'date'   => $cust_pay_void->_date,
      'desc'   => "Payment $info voided ".
                  time2str("%D", $cust_pay_void->void_date).
                  " by ". $cust_pay_void->otaker. '',
      'void_payment' => $cust_pay_void->paid,
    };
  
  }
  #credits (some false laziness w/payments)
  foreach my $cust_credit ($cust_main->cust_credit) {
    my @cust_credit_bill = $cust_credit->cust_credit_bill;
    my @cust_credit_refund = $cust_credit->cust_credit_refund;
    my( $pre, $post, $desc, $apply, $ext ) = ( '', '', '', '', '' );
    if (    scalar(@cust_credit_bill)   == 0
         && scalar(@cust_credit_refund) == 0 ) {
      #completely unapplied
      $pre = 'Unapplied ';
      $post = '';
      $apply = qq! (apply)';
    } elsif (    scalar(@cust_credit_bill)   == 1
              && scalar(@cust_credit_refund) == 0
              && $cust_credit->credited == 0      ) {
      #applied to one invoice, the usual situation
      $desc = ' applied to Invoice #'. $cust_credit_bill[0]->invnum;
    } elsif (    scalar(@cust_credit_bill)   == 0
              && scalar(@cust_credit_refund) == 1
              && $cust_credit->credited == 0      ) {
      #applied to one refund
      $desc = ' refunded on '.  time2str("%D", $cust_credit_refund[0]->_date);
    } else {
      #complicated
      $desc = '
';
      foreach my $app ( sort { $a->_date <=> $b->_date }
                             ( @cust_credit_bill, @cust_credit_refund ) ) {
        if ( $app->isa('FS::cust_credit_bill') ) {
          $desc .= '  '.
                   '$'. $app->amount.
                   ' applied to Invoice #'. $app->invnum.
                   '
';
                   #' on '. time2str("%D", $app->_date).
        } elsif ( $app->isa('FS::cust_credit_refund') ) {
          $desc .= '  '.
                   '$'. $app->amount.
                   ' refunded on'. time2str("%D", $app->_date).
                   '
';
        } else {
          die "$app is not a FS::cust_credit_bill or a FS::cust_credit_refund";
        }
      }
      if ( $cust_credit->credited > 0 ) {
        $desc .= '  $'.
                 $cust_credit->credited. ' unapplied'.
                 qq! (apply)'.
                 '
';
      }
    }
#
    my $delete = '';
    if ( $cust_credit->closed !~ /^Y/i && $conf->exists('deletecredits') ) {
      $delete = qq! (!.
                qq!delete)!;
    }
    
    my $unapply = '';
    if (    $cust_credit->closed !~ /^Y/i
         && $conf->exists('unapplycredits')
         && scalar(@cust_credit_bill)       ) {
      $unapply = qq! (!.
                 qq!unapply)!;
    }
    
    push @history, {
      'date'   => $cust_credit->_date,
      'desc'   => $pre. "Credit$post by ". $cust_credit->otaker.
                  ' ('. $cust_credit->reason. ')'.
                  "$desc$apply$delete$unapply",
      'credit' => $cust_credit->amount,
    };
  }
  #refunds
  foreach my $cust_refund ($cust_main->cust_refund) {
    my $payby = $cust_refund->payby;
    my $payinfo = $payby eq 'CARD'
                    ? $cust_refund->payinfo_masked
                    : $cust_refund->payinfo;
    $payby =~ s/^BILL$/Check #/ if $payinfo;
    $payby =~ s/^CHEK$/Electronic check /;
    $payby =~ s/^(CARD|COMP)$/$1 /;
    push @history, {
      'date'   => $cust_refund->_date,
      'desc'   => "Refund ($payby$payinfo) by ". $cust_refund->otaker,
      'refund' => $cust_refund->refund,
    };
  
  }
  
  %>
  
  <%= table() %>
  
    | Date | Description | Charge | Payment | In-house Credit
 | Refund | Balance | 
  <%
  #display payment history
  my %target;
  my $balance = 0;
  foreach my $item ( sort { $a->{'date'} <=> $b->{'date'} } @history ) {
    my $charge  = exists($item->{'charge'})
                    ? sprintf('$%.2f', $item->{'charge'})
                    : '';
    my $payment = exists($item->{'payment'})
                    ? sprintf('- $%.2f', $item->{'payment'})
                    : '';
    $payment ||= sprintf('- $%.2f', $item->{'void_payment'})
      if exists($item->{'void_payment'});
    my $credit  = exists($item->{'credit'})
                    ? sprintf('- $%.2f', $item->{'credit'})
                    : '';
    my $refund  = exists($item->{'refund'})
                    ? sprintf('$%.2f', $item->{'refund'})
                    : '';
    my $target = exists($item->{'target'}) ? $item->{'target'} : '';
    $balance += $item->{'charge'}  if exists $item->{'charge'};
    $balance -= $item->{'payment'} if exists $item->{'payment'};
    $balance -= $item->{'credit'}  if exists $item->{'credit'};
    $balance += $item->{'refund'}  if exists $item->{'refund'};
    $balance = sprintf("%.2f", $balance);
    $balance =~ s/^\-0\.00$/0.00/; #yay ieee fp
    ( my $showbalance = '$'. $balance ) =~ s/^\$\-/- \$/;
  %>
  
    
      | <% unless ( !$target || $target{$target}++ ) { %>
          
        <% } %>
        <%= time2str("%D",$item->{'date'}) %>
        <% if ( $target && $target{$target} == 1 ) { %>
          
        <% } %> | <%= $item->{'desc'} %> | <%= $charge  %> | <%= $payment %> | <%= $credit  %> | <%= $refund  %> | <%= $showbalance %> | 
  <% } %>
  
  
<% } %>