Initial revision
authorivan <ivan>
Fri, 17 Apr 1998 05:37:07 +0000 (05:37 +0000)
committerivan <ivan>
Fri, 17 Apr 1998 05:37:07 +0000 (05:37 +0000)
13 files changed:
htdocs/edit/process/cust_credit.cgi [new file with mode: 0755]
htdocs/edit/process/cust_main.cgi [new file with mode: 0755]
htdocs/edit/process/cust_pay.cgi [new file with mode: 0755]
htdocs/edit/process/cust_pkg.cgi [new file with mode: 0755]
htdocs/edit/process/svc_acct.cgi [new file with mode: 0755]
htdocs/misc/bill.cgi [new file with mode: 0755]
htdocs/misc/cancel-unaudited.cgi [new file with mode: 0755]
htdocs/misc/expire_pkg.cgi [new file with mode: 0755]
htdocs/misc/susp_pkg.cgi [new file with mode: 0755]
htdocs/misc/unsusp_pkg.cgi [new file with mode: 0755]
htdocs/search/cust_bill.cgi [new file with mode: 0755]
htdocs/view/cust_pkg.cgi [new file with mode: 0755]
htdocs/view/svc_domain.cgi [new file with mode: 0755]

diff --git a/htdocs/edit/process/cust_credit.cgi b/htdocs/edit/process/cust_credit.cgi
new file mode 100755 (executable)
index 0000000..e660b4c
--- /dev/null
@@ -0,0 +1,70 @@
+#!/usr/bin/perl -Tw
+#
+# process/cust_credit.cgi: Add a credit (process form)
+#
+# Usage: post form to:
+#        http://server.name/path/cust_credit.cgi
+#
+# Note: Should be run setuid root as user nobody.
+#
+# ivan@voicenet.com 96-dec-05 -> 96-dec-08
+#
+# post a refund if $new_paybatch
+# ivan@voicenet.com 96-dec-08
+#
+# refunds are no longer applied against a specific payment (paybatch)
+# paybatch field removed
+# ivan@voicenet.com 97-apr-22
+#
+# rewrite ivan@sisd.com 98-mar-16
+#
+# Changes to allow page to work at a relative position in server
+#       bmccane@maxbaud.net     98-apr-3
+
+use strict;
+use CGI::Request;
+use FS::UID qw(cgisuidsetup getotaker);
+use FS::cust_credit;
+
+my($req)=new CGI::Request; # create form object
+cgisuidsetup($req->cgi);
+
+$req->param('custnum') =~ /^(\d*)$/ or die "Illegal custnum!";
+my($custnum)=$1;
+
+$req->param('otaker',getotaker);
+
+my($new) = create FS::cust_credit ( {
+  map {
+    $_, $req->param($_);
+  } qw(custnum _date amount otaker reason)
+} );
+
+my($error);
+$error=$new->insert;
+&idiot($error) if $error;
+
+#no errors, no refund, so view our credit.
+$req->cgi->redirect("../../view/cust_main.cgi?$custnum#history");
+
+sub idiot {
+  my($error)=@_;
+  CGI::Base::SendHeaders(); # one guess
+  print <<END;
+<HTML>
+  <HEAD>
+    <TITLE>Error posting credit/refund</TITLE>
+  </HEAD>
+  <BODY>
+    <CENTER>
+    <H4>Error posting credit/refund</H4>
+    </CENTER>
+    Your update did not occur because of the following error:
+    <P><B>$error</B>
+    <P>Hit the <I>Back</I> button in your web browser, correct this mistake, and press the <I>Post</I> button again.
+  </BODY>
+</HTML>
+END
+
+}
+
diff --git a/htdocs/edit/process/cust_main.cgi b/htdocs/edit/process/cust_main.cgi
new file mode 100755 (executable)
index 0000000..7664dfc
--- /dev/null
@@ -0,0 +1,102 @@
+#!/usr/bin/perl -Tw
+#
+# process/cust_main.cgi: Edit a customer (process form)
+#
+# Usage: post form to:
+#        http://server.name/path/cust_main.cgi
+#
+# Note: Should be run setuid root as user nobody.
+#
+# ivan@voicenet.com 96-dec-04
+#
+# added referral check
+# ivan@voicenet.com 97-jun-4
+#
+# rewrote for new API
+# ivan@voicenet.com 97-jul-28
+#
+# same as above (again) and clean up some stuff ivan@sisd.com 98-feb-23
+#
+# Changes to allow page to work at a relative position in server
+# Changed 'day' to 'daytime' because Pg6.3 reserves the day word
+#       bmccane@maxbaud.net     98-apr-3
+
+use strict;
+use CGI::Request;
+use CGI::Carp qw(fatalsToBrowser);
+use FS::UID qw(cgisuidsetup);
+use FS::Record qw(qsearchs);
+use FS::cust_main;
+
+my($req)=new CGI::Request; # create form object
+
+&cgisuidsetup($req->cgi);
+
+#create new record object
+
+#unmunge agentnum
+$req->param('agentnum', 
+  (split(/:/, ($req->param('agentnum'))[0] ))[0]
+);
+
+#unmunge tax
+$req->param('tax','') unless defined($req->param('tax'));
+
+#unmunge refnum
+$req->param('refnum',
+  (split(/:/, ($req->param('refnum'))[0] ))[0]
+);
+
+#unmunge state/county
+$req->param('state') =~ /^(\w+)( \((\w+)\))?$/;
+$req->param('state', $1);
+$req->param('county', $3 || '');
+
+my($new) = create FS::cust_main ( {
+  map {
+    $_, $req->param("$_") || ''
+  } qw(custnum agentnum last first ss company address1 address2 city county
+       state zip country daytime night fax payby payinfo paydate payname tax
+       otaker refnum)
+} );
+
+if ( $new->custnum eq '' ) {
+
+  my($error)=$new->insert;
+  &idiot($error) if $error;
+
+} else { #create old record object
+
+  my($old) = qsearchs( 'cust_main', { 'custnum', $new->custnum } ); 
+  &idiot("Old record not found!") unless $old;
+  my($error)=$new->replace($old);
+  &idiot($error) if $error;
+
+}
+
+my($custnum)=$new->custnum;
+$req->cgi->redirect("../../view/cust_main.cgi?$custnum#cust_main");
+
+sub idiot {
+  my($error)=@_;
+  CGI::Base::SendHeaders(); # one guess
+  print <<END;
+<HTML>
+  <HEAD>
+    <TITLE>Error updating customer information</TITLE>
+  </HEAD>
+  <BODY>
+    <CENTER>
+    <H4>Error updating customer information</H4>
+    </CENTER>
+    Your update did not occur because of the following error:
+    <P><B>$error</B>
+    <P>Hit the <I>Back</I> button in your web browser, correct this mistake, and submit the form again.
+  </BODY>
+</HTML>
+END
+
+  exit;
+
+}
+
diff --git a/htdocs/edit/process/cust_pay.cgi b/htdocs/edit/process/cust_pay.cgi
new file mode 100755 (executable)
index 0000000..9ec9753
--- /dev/null
@@ -0,0 +1,57 @@
+#!/usr/bin/perl -Tw
+#
+# process/cust_pay.cgi: Add a payment (process form)
+#
+# Usage: post form to:
+#        http://server.name/path/cust_pay.cgi
+#
+# Note: Should be run setuid root as user nobody.
+#
+# ivan@voicenet.com 96-dec-11
+#
+# rewrite ivan@sisd.com 98-mar-16
+#
+# Changes to allow page to work at a relative position in server
+#       bmccane@maxbaud.net     98-apr-3
+
+use strict;
+use CGI::Request;
+use FS::UID qw(cgisuidsetup);
+use FS::cust_pay qw(fields);
+
+my($req)=new CGI::Request;
+&cgisuidsetup($req->cgi);
+
+$req->param('invnum') =~ /^(\d*)$/ or die "Illegal svcnum!";
+my($invnum)=$1;
+
+my($new) = create FS::cust_pay ( {
+  map {
+    $_, $req->param($_);
+  } qw(invnum paid _date payby payinfo paybatch)
+} );
+
+my($error);
+$error=$new->insert;
+
+if ($error) { #error!
+  CGI::Base::SendHeaders(); # one guess
+  print <<END;
+<HTML>
+  <HEAD>
+    <TITLE>Error posting payment</TITLE>
+  </HEAD>
+  <BODY>
+    <CENTER>
+    <H4>Error posting payment</H4>
+    </CENTER>
+    Your update did not occur because of the following error:
+    <P><B>$error</B>
+    <P>Hit the <I>Back</I> button in your web browser, correct this mistake, and press the <I>Post</I> button again.
+  </BODY>
+</HTML>
+END
+} else { #no errors!
+  $req->cgi->redirect("../../view/cust_bill.cgi?$invnum");
+}
+
diff --git a/htdocs/edit/process/cust_pkg.cgi b/htdocs/edit/process/cust_pkg.cgi
new file mode 100755 (executable)
index 0000000..6f5bc87
--- /dev/null
@@ -0,0 +1,73 @@
+#!/usr/bin/perl -Tw
+#
+# process/cust_pkg.cgi: Add/edit packages (process form)
+#
+# this is for changing packages around, not for editing things within the
+# package
+#
+# Usage: post form to:
+#        http://server.name/path/cust_pkg.cgi
+#
+# Note: Should be run setuid root as user nobody.
+#
+# ivan@voicenet.com 97-mar-21 - 97-mar-24
+#
+# rewrote for new API
+# ivan@voicenet.com 97-jul-7 - 15
+#
+# &cgisuidsetup($cgi) ivan@sisd.com 98-mar-7
+#
+# Changes to allow page to work at a relative position in server
+#       bmccane@maxbaud.net     98-apr-3
+
+use strict;
+use CGI::Request;
+use CGI::Carp qw(fatalsToBrowser);
+use FS::UID qw(cgisuidsetup);
+use FS::cust_pkg;
+
+my($req)=new CGI::Request; # create form object
+
+&cgisuidsetup($req->cgi);
+
+#untaint custnum
+$req->param('new_custnum') =~ /^(\d+)$/;
+my($custnum)=$1;
+
+my(@remove_pkgnums) = map {
+  /^(\d+)$/ or die "Illegal remove_pkg value!";
+  $1;
+} $req->param('remove_pkg');
+
+my(@pkgparts);
+my($pkgpart);
+foreach $pkgpart ( map /^pkg(\d+)$/ ? $1 : (), $req->params ) {
+  my($num_pkgs)=$req->param("pkg$pkgpart");
+  while ( $num_pkgs-- ) {
+    push @pkgparts,$pkgpart;
+  }
+}
+
+my($error) = FS::cust_pkg::order($custnum,\@pkgparts,\@remove_pkgnums);
+
+if ($error) {
+  CGI::Base::SendHeaders();
+  print <<END;
+<HTML>
+  <HEAD>
+    <TITLE>Error updating packages</TITLE>
+  </HEAD>
+  <BODY>
+    <CENTER>
+    <H4>Error updating packages</H4>
+    </CENTER>
+    Your update did not occur because of the following error:
+    <P><B>$error</B>
+    <P>Hit the <I>Back</I> button in your web browser, correct this mistake, and submit the form again.
+  </BODY>
+</HTML>
+END
+} else {
+  $req->cgi->redirect("../../view/cust_main.cgi?$custnum#cust_pkg");
+}
+
diff --git a/htdocs/edit/process/svc_acct.cgi b/htdocs/edit/process/svc_acct.cgi
new file mode 100755 (executable)
index 0000000..8d77ba7
--- /dev/null
@@ -0,0 +1,87 @@
+#!/usr/bin/perl -Tw
+#
+# process/svc_acct.cgi: Add/edit a customer (process form)
+#
+# Usage: post form to:
+#        http://server.name/path/svc_acct.cgi
+#
+# Note: Should br run setuid root as user nobody.
+#
+# ivan@voicenet.com 96-dec-18
+#
+# Changed /u to /u2
+# ivan@voicenet.com 97-may-6
+#
+# rewrote for new API
+# ivan@voicenet.com 97-jul-17 - 21
+#
+# no FS::Search, FS::svc_acct creates FS::cust_svc record, used for adding
+# and editing ivan@sisd.com 98-mar-8
+#
+# Changes to allow page to work at a relative position in server
+# Changed 'password' to '_password' because Pg6.3 reserves the password word
+#       bmccane@maxbaud.net     98-apr-3
+
+use strict;
+use CGI::Request;
+use CGI::Carp qw(fatalsToBrowser);
+use FS::UID qw(cgisuidsetup);
+use FS::Record qw(qsearchs);
+use FS::svc_acct;
+
+my($req) = new CGI::Request; # create form object
+&cgisuidsetup($req->cgi);
+
+$req->param('svcnum') =~ /^(\d*)$/ or die "Illegal svcnum!";
+my($svcnum)=$1;
+
+my($old)=qsearchs('svc_acct',{'svcnum'=>$svcnum}) if $svcnum;
+
+#unmunge popnum
+$req->param('popnum', (split(/:/, $req->param('popnum') ))[0] );
+
+#unmunge passwd
+if ( $req->param('_password') eq '*HIDDEN*' ) {
+  $req->param('_password',$old->getfield('_password'));
+}
+
+my($new) = create FS::svc_acct ( {
+  map {
+    $_, $req->param($_);
+  } qw(svcnum pkgnum svcpart username _password popnum uid gid finger dir
+    shell quota slipip)
+} );
+
+if ( $svcnum ) {
+  my($error) = $new->replace($old);
+  &idiot($error) if $error;
+} else {
+  my($error) = $new->insert;
+  &idiot($error) if $error;
+  $svcnum = $new->getfield('svcnum');
+}
+
+#no errors, view account
+$req->cgi->redirect("../../view/svc_acct.cgi?" . $svcnum );
+
+sub idiot {
+  my($error)=@_;
+  CGI::Base::SendHeaders(); # one guess
+  print <<END;
+<HTML>
+  <HEAD>
+    <TITLE>Error adding/updating account</TITLE>
+  </HEAD>
+  <BODY>
+    <CENTER>
+    <H4>Error adding/updating account</H4>
+    </CENTER>
+    Your update did not occur because of the following error:
+    <P><B>$error</B>
+    <P>Hit the <I>Back</I> button in your web browser, correct this mistake, and submit the form again.
+  </BODY>
+</HTML>
+END
+  exit;
+}
+
diff --git a/htdocs/misc/bill.cgi b/htdocs/misc/bill.cgi
new file mode 100755 (executable)
index 0000000..d41f6d1
--- /dev/null
@@ -0,0 +1,66 @@
+#!/usr/bin/perl -Tw
+#
+# s/FS:Search/FS::Record/ and cgisuidsetup($cgi) ivan@sisd.com 98-mar-13
+#
+# Changes to allow page to work at a relative position in server
+#       bmccane@maxbaud.net     98-apr-3
+
+use strict;
+use CGI::Base qw(:DEFAULT :CGI);
+use CGI::Carp qw(fatalsToBrowser);
+use FS::UID qw(cgisuidsetup);
+use FS::Record qw(qsearchs);
+use FS::Bill;
+
+my($cgi) = new CGI::Base;
+$cgi->get;
+&cgisuidsetup($cgi);
+
+#untaint custnum
+$QUERY_STRING =~ /^(\d*)$/;
+my($custnum)=$1;
+my($cust_main)=qsearchs('cust_main',{'custnum'=>$custnum});
+die "Can't find customer!\n" unless $cust_main;
+
+# ? 
+bless($cust_main,"FS::Bill");
+
+my($error);
+
+$error = $cust_main->bill(
+#                          'time'=>$time
+                         );
+&idiot($error) if $error;
+
+$error = $cust_main->collect(
+#                             'invoice-time'=>$time,
+#                             'batch_card'=> 'yes',
+                             'batch_card'=> 'no',
+                             'report_badcard'=> 'yes',
+                            );
+&idiot($error) if $error;
+
+$cgi->redirect("../view/cust_main.cgi?$custnum#history");
+
+sub idiot {
+  my($error)=@_;
+  CGI::Base::SendHeaders(); # one guess
+  print <<END;
+<HTML>
+  <HEAD>
+    <TITLE>Error billing customer</TITLE>
+  </HEAD>
+  <BODY>
+    <CENTER>
+    <H4>Error billing customer</H4>
+    </CENTER>
+    Your update did not occur because of the following error:
+    <P><B>$error</B>
+  </BODY>
+</HTML>
+END
+
+  exit;
+
+}
+
diff --git a/htdocs/misc/cancel-unaudited.cgi b/htdocs/misc/cancel-unaudited.cgi
new file mode 100755 (executable)
index 0000000..929274f
--- /dev/null
@@ -0,0 +1,85 @@
+#!/usr/bin/perl -Tw
+#
+# cancel-unaudited.cgi: Cancel an unaudited account
+#
+# Usage: cancel-unaudited.cgi svcnum
+#        http://server.name/path/cancel-unaudited.cgi pkgnum
+#
+# Note: Should be run setuid freeside as user nobody
+#
+# ivan@voicenet.com 97-apr-23
+#
+# rewrote for new API
+# ivan@voicenet.com 97-jul-21
+#
+# Search->Record, cgisuidsetup($cgi) ivan@sids.com 98-mar-19
+#
+# Changes to allow page to work at a relative position in server
+#       bmccane@maxbaud.net     98-apr-3
+
+use strict;
+use CGI::Base qw(:DEFAULT :CGI); # CGI module
+use CGI::Carp qw(fatalsToBrowser);
+use FS::UID qw(cgisuidsetup);
+use FS::Record qw(qsearchs);
+use FS::cust_svc;
+use FS::svc_acct;
+
+my($cgi) = new CGI::Base;
+$cgi->get;
+&cgisuidsetup($cgi);
+#untaint svcnum
+$QUERY_STRING =~ /^(\d+)$/;
+my($svcnum)=$1;
+
+my($svc_acct) = qsearchs('svc_acct',{'svcnum'=>$svcnum});
+&idiot("Unknown svcnum!") unless $svc_acct;
+
+my($cust_svc) = qsearchs('cust_svc',{'svcnum'=>$svcnum});
+&idiot(qq!This account has already been audited.  Cancel the 
+    <A HREF="../view/cust_pkg.cgi?! . $cust_svc->getfield('pkgnum') .
+    qq!pkgnum"> package</A> instead.!) 
+  if $cust_svc->getfield('pkgnum') ne '';
+
+local $SIG{HUP} = 'IGNORE';
+local $SIG{INT} = 'IGNORE';
+local $SIG{QUIT} = 'IGNORE';
+local $SIG{TERM} = 'IGNORE';
+local $SIG{TSTP} = 'IGNORE';
+
+my($error);
+
+bless($svc_acct,"FS::svc_acct");
+$error = $svc_acct->cancel;
+&idiot($error) if $error;
+$error = $svc_acct->delete;
+&idiot($error) if $error;
+
+bless($cust_svc,"FS::cust_svc");
+$error = $cust_svc->delete;
+&idiot($error) if $error;
+
+$cgi->redirect("../");
+
+sub idiot {
+  my($error)=@_;
+  SendHeaders();
+  print <<END;
+<HTML>
+  <HEAD>
+    <TITLE>Error cancelling account</TITLE>
+  </HEAD>
+  <BODY>
+    <CENTER>
+    <H1>Error cancelling account</H1>
+    </CENTER>
+    <HR>
+    There has been an error cancelling this acocunt:  $error
+  </BODY>
+  </HEAD>
+</HTML>
+END
+  exit;
+}
+
diff --git a/htdocs/misc/expire_pkg.cgi b/htdocs/misc/expire_pkg.cgi
new file mode 100755 (executable)
index 0000000..1635166
--- /dev/null
@@ -0,0 +1,71 @@
+#!/usr/bin/perl -Tw
+#
+# expire_pkg.cgi: Expire a package
+#
+# Usage: post form to:
+#        http://server.name/path/expire_pkg.cgi
+#
+# Note: Should be run setuid freeside as user nobody
+#
+# based on susp_pkg
+# ivan@voicenet.com 97-jul-29
+#
+# ivan@sisd.com 98-mar-17 FS::Search->FS::Record
+#
+# Changes to allow page to work at a relative position in server
+#       bmccane@maxbaud.net     98-apr-3
+
+use strict;
+use Date::Parse;
+use CGI::Request;
+use CGI::Carp qw(fatalsToBrowser);
+use FS::UID qw(cgisuidsetup);
+use FS::Record qw(qsearchs);
+use FS::cust_pkg;
+
+my($req) = new CGI::Request;
+&cgisuidsetup($req->cgi);
+
+#untaint date & pkgnum
+
+my($date);
+if ( $req->param('date') ) {
+  str2time($req->param('date')) =~ /^(\d+)$/ or die "Illegal date";
+  $date=$1;
+} else {
+  $date='';
+}
+
+$req->param('pkgnum') =~ /^(\d+)$/ or die "Illegal pkgnum";
+my($pkgnum)=$1;
+
+my($cust_pkg) = qsearchs('cust_pkg',{'pkgnum'=>$pkgnum});
+my(%hash)=$cust_pkg->hash;
+$hash{expire}=$date;
+my($new)=create FS::cust_pkg ( \%hash );
+my($error) = $new->replace($cust_pkg);
+&idiot($error) if $error;
+
+$req->cgi->redirect("../view/cust_main.cgi?".$cust_pkg->getfield('custnum'));
+
+sub idiot {
+  my($error)=@_;
+  SendHeaders();
+  print <<END;
+<HTML>
+  <HEAD>
+    <TITLE>Error expiring package</TITLE>
+  </HEAD>
+  <BODY>
+    <CENTER>
+    <H1>Error expiring package</H1>
+    </CENTER>
+    <HR>
+    There has been an error expiring this package:  $error
+  </BODY>
+  </HEAD>
+</HTML>
+END
+  exit;
+}
+
diff --git a/htdocs/misc/susp_pkg.cgi b/htdocs/misc/susp_pkg.cgi
new file mode 100755 (executable)
index 0000000..7b23cae
--- /dev/null
@@ -0,0 +1,68 @@
+#!/usr/bin/perl -Tw
+#
+# susp_pkg.cgi: Suspend a package
+#
+# Usage: susp_pkg.cgi pkgnum
+#        http://server.name/path/susp_pkg.cgi pkgnum
+#
+# Note: Should be run setuid freeside as user nobody
+#
+# probably should generalize this to do cancels, suspensions, unsuspensions, etc.
+#
+# ivan@voicenet.com 97-feb-27
+#
+# now redirects to enter comments
+# ivan@voicenet.com 97-may-8
+#
+# rewrote for new API
+# ivan@voicenet.com 97-jul-21
+#
+# FS::Search -> FS::Record ivan@sisd.com 98-mar-17
+#
+# Changes to allow page to work at a relative position in server
+#       bmccane@maxbaud.net     98-apr-3
+
+use strict;
+use CGI::Base qw(:DEFAULT :CGI); # CGI module
+use CGI::Carp qw(fatalsToBrowser);
+use FS::UID qw(cgisuidsetup);
+use FS::Record qw(qsearchs);
+use FS::cust_pkg;
+
+my($cgi) = new CGI::Base;
+$cgi->get;
+&cgisuidsetup($cgi);
+#untaint pkgnum
+$QUERY_STRING =~ /^(\d+)$/ || die "Illegal pkgnum";
+my($pkgnum)=$1;
+
+my($cust_pkg) = qsearchs('cust_pkg',{'pkgnum'=>$pkgnum});
+
+bless($cust_pkg,'FS::cust_pkg');
+my($error)=$cust_pkg->suspend;
+&idiot($error) if $error;
+
+$cgi->redirect("../view/cust_main.cgi?".$cust_pkg->getfield('custnum'));
+
+sub idiot {
+  my($error)=@_;
+  SendHeaders();
+  print <<END;
+<HTML>
+  <HEAD>
+    <TITLE>Error suspending package</TITLE>
+  </HEAD>
+  <BODY>
+    <CENTER>
+    <H1>Error suspending package</H1>
+    </CENTER>
+    <HR>
+    There has been an error suspending this package:  $error
+  </BODY>
+  </HEAD>
+</HTML>
+END
+  exit;
+}
+
diff --git a/htdocs/misc/unsusp_pkg.cgi b/htdocs/misc/unsusp_pkg.cgi
new file mode 100755 (executable)
index 0000000..2f340c6
--- /dev/null
@@ -0,0 +1,68 @@
+#!/usr/bin/perl -Tw
+#
+# susp_pkg.cgi: Unsuspend a package
+#
+# Usage: susp_pkg.cgi pkgnum
+#        http://server.name/path/susp_pkg.cgi pkgnum
+#
+# Note: Should be run setuid freeside as user nobody
+#
+# probably should generalize this to do cancels, suspensions, unsuspensions, etc.
+#
+# ivan@voicenet.com 97-feb-27
+#
+# now redirects to enter comments
+# ivan@voicenet.com 97-may-8
+#
+# rewrote for new API
+# ivan@voicenet.com 97-jul-21
+#
+# FS::Search -> FS::Record ivan@sisd.com 98-mar-17
+#
+# Changes to allow page to work at a relative position in server
+#       bmccane@maxbaud.net     98-apr-3
+
+use strict;
+use CGI::Base qw(:DEFAULT :CGI); # CGI module
+use CGI::Carp qw(fatalsToBrowser);
+use FS::UID qw(cgisuidsetup);
+use FS::Record qw(qsearchs);
+use FS::cust_pkg;
+
+my($cgi) = new CGI::Base;
+$cgi->get;
+&cgisuidsetup($cgi);
+#untaint pkgnum
+$QUERY_STRING =~ /^(\d+)$/ || die "Illegal pkgnum";
+my($pkgnum)=$1;
+
+my($cust_pkg) = qsearchs('cust_pkg',{'pkgnum'=>$pkgnum});
+
+bless($cust_pkg,'FS::cust_pkg');
+my($error)=$cust_pkg->unsuspend;
+&idiot($error) if $error;
+
+$cgi->redirect("../view/cust_main.cgi?".$cust_pkg->getfield('custnum'));
+
+sub idiot {
+  my($error)=@_;
+  SendHeaders();
+  print <<END;
+<HTML>
+  <HEAD>
+    <TITLE>Error unsuspending package</TITLE>
+  </HEAD>
+  <BODY>
+    <CENTER>
+    <H1>Error unsuspending package</H1>
+    </CENTER>
+    <HR>
+    There has been an error unsuspending this package:  $error
+  </BODY>
+  </HEAD>
+</HTML>
+END
+  exit;
+}
+
diff --git a/htdocs/search/cust_bill.cgi b/htdocs/search/cust_bill.cgi
new file mode 100755 (executable)
index 0000000..5be84b7
--- /dev/null
@@ -0,0 +1,46 @@
+#!/usr/bin/perl -Tw
+#
+# cust_bill.cgi: Search for invoices (process form)
+#
+# Usage: post form to:
+#        http://server.name/path/cust_bill.cgi
+#
+# Note: Should be run setuid freeside as user nobody.
+#
+# ivan@voicenet.com 97-apr-4
+#
+# Changes to allow page to work at a relative position in server
+#       bmccane@maxbaud.net     98-apr-3
+
+use strict;
+use CGI::Request;
+use FS::UID qw(cgisuidsetup);
+use FS::Record qw(qsearchs);
+
+my($req)=new CGI::Request;
+cgisuidsetup($req->cgi);
+
+$req->param('invnum') =~ /^\s*(FS-)?(\d+)\s*$/;
+my($invnum)=$2;
+
+if ( qsearchs('cust_bill',{'invnum'=>$invnum}) ) {
+  $req->cgi->redirect("../view/cust_bill.cgi?$invnum");  #redirect
+} else { #error
+  CGI::Base::SendHeaders(); # one guess
+  print <<END;
+<HTML>
+  <HEAD>
+    <TITLE>Invoice Search Error</TITLE>
+  </HEAD>
+  <BODY>
+    <CENTER>
+    <H3>Invoice Search Error</H3>
+    <HR>
+    Invoice not found.
+    </CENTER>
+  </BODY>
+</HTML>
+END
+
+}
+
diff --git a/htdocs/view/cust_pkg.cgi b/htdocs/view/cust_pkg.cgi
new file mode 100755 (executable)
index 0000000..04e3832
--- /dev/null
@@ -0,0 +1,181 @@
+#!/usr/bin/perl -Tw
+#
+# cust_pkg.cgi: View a package
+#
+# Usage: cust_pkg.cgi pkgnum
+#        http://server.name/path/cust_pkg.cgi?pkgnum
+#
+# Note: Should be run setuid freeside as user nobody.
+#
+# ivan@voicenet.com 96-dec-15
+#
+# services section needs to be cleaned up, needs to display extraneous
+# entries in cust_pkg!
+# ivan@voicenet.com 96-dec-31
+#
+# added navigation bar
+# ivan@voicenet.com 97-jan-30
+#
+# changed and fixed up suspension and cancel stuff, now you can't add
+# services to a cancelled package
+# ivan@voicenet.com 97-feb-27
+#
+# rewrote for new API, still needs to be cleaned up!
+# ivan@voicenet.com 97-jul-29
+#
+# no FS::Search ivan@sisd.com 98-mar-7
+
+use strict;
+use Date::Format;
+use CGI::Base qw(:DEFAULT :CGI); # CGI module
+use FS::UID qw(cgisuidsetup);
+use FS::Record qw(qsearch qsearchs);
+
+my($cgi) = new CGI::Base;
+$cgi->get;
+&cgisuidsetup($cgi);
+
+my(%uiview,%uiadd);
+my($part_svc);
+foreach $part_svc ( qsearch('part_svc',{}) ) {
+  $uiview{$part_svc->svcpart}="../view/". $part_svc->svcdb . ".cgi";
+  $uiadd{$part_svc->svcpart}="../edit/". $part_svc->svcdb . ".cgi";
+}
+
+SendHeaders(); # one guess.
+print <<END;
+<HTML>
+  <HEAD>
+    <TITLE>Package View</TITLE>
+  </HEAD>
+  <BODY>
+    <CENTER>
+    <H1>Package View</H1>
+    </CENTER>
+    <BASEFONT SIZE=3>
+END
+
+#untaint pkgnum
+$QUERY_STRING =~ /^(\d+)$/;
+my($pkgnum)=$1;
+
+#get package record
+my($cust_pkg)=qsearchs('cust_pkg',{'pkgnum'=>$pkgnum});
+die "No package!" unless $cust_pkg;
+my($part_pkg)=qsearchs('part_pkg',{'pkgpart'=>$cust_pkg->getfield('pkgpart')});
+
+#nav bar
+my($custnum)=$cust_pkg->getfield('custnum');
+print qq!<CENTER><A HREF="../view/cust_main.cgi?$custnum">View this customer!,
+      qq! (#$custnum)</A> | <A HREF="../">Main menu</A></CENTER><BR>!;
+
+#print info
+my($susp,$cancel,$expire)=(
+  $cust_pkg->getfield('susp'),
+  $cust_pkg->getfield('cancel'),
+  $cust_pkg->getfield('expire'),
+);
+print "<FONT SIZE=+1><CENTER>Package #<B>$pkgnum</B></FONT>";
+print qq!<BR><A HREF="#package">Package Information</A>!;
+print qq! | <A HREF="#services">Service Information</A>! unless $cancel;
+print qq!</CENTER><HR>\n!;
+
+my($pkg,$comment)=($part_pkg->getfield('pkg'),$part_pkg->getfield('comment'));
+print qq!<A NAME="package"><CENTER><FONT SIZE=+1>Package Information!,
+      qq!</FONT></A>!;
+print qq!<BR><A HREF="../unimp.html">Edit this information</A></CENTER>!;
+print "<P>Package: <B>$pkg - $comment</B>";
+
+my($setup,$bill)=($cust_pkg->getfield('setup'),$cust_pkg->getfield('bill'));
+print "<BR>Setup: <B>", $setup ? time2str("%D",$setup) : "(Not setup)" ,"</B>";
+print "<BR>Next bill: <B>", $bill ? time2str("%D",$bill) : "" ,"</B>";
+
+if ($susp) {
+  print "<BR>Suspended: <B>", time2str("%D",$susp), "</B>";
+  print qq! <A HREF="../misc/unsusp_pkg.cgi?$pkgnum">Unsuspend</A>! unless $cancel;
+} else {
+  print qq!<BR><A HREF="../misc/susp_pkg.cgi?$pkgnum">Suspend</A>! unless $cancel;
+}
+
+if ($expire) {
+  print "<BR>Expire: <B>", time2str("%D",$expire), "</B>";
+}
+  print <<END;
+<FORM ACTION="../misc/expire_pkg.cgi" METHOD="post">
+<INPUT TYPE="hidden" NAME="pkgnum" VALUE="$pkgnum">
+Expire (date): <INPUT TYPE="text" NAME="date" VALUE="" >
+<INPUT TYPE="submit" VALUE="Cancel later">
+END
+
+if ($cancel) {
+  print "<BR>Cancelled: <B>", time2str("%D",$cancel), "</B>";
+} else {
+  print qq!<BR><A HREF="../misc/cancel_pkg.cgi?$pkgnum">Cancel now</A>!;
+}
+
+#otaker
+my($otaker)=$cust_pkg->getfield('otaker');
+print "<P>Order taken by <B>$otaker</B>";
+
+unless ($cancel) {
+
+  #services
+  print <<END;
+<HR><A NAME="services"><CENTER><FONT SIZE=+1>Service Information</FONT></A>
+<BR>Click on service to view/edit/add service.</CENTER><BR>
+<CENTER><B>Do NOT pick the "Link to existing" option unless you are auditing!!!</B></CENTER>
+<CENTER><TABLE BORDER=4>
+<TR><TH>Service</TH>
+END
+
+  #list of services this pkgpart includes
+  my($pkg_svc,%pkg_svc);
+  foreach $pkg_svc ( qsearch('pkg_svc',{'pkgpart'=> $cust_pkg->pkgpart }) ) {
+    $pkg_svc{$pkg_svc->svcpart} = $pkg_svc->quantity if $pkg_svc->quantity;
+  }
+
+  #list of records from cust_svc
+  my($svcpart);
+  foreach $svcpart (sort {$a <=> $b} keys %pkg_svc) {
+
+    my($svc)=qsearchs('part_svc',{'svcpart'=>$svcpart})->getfield('svc');
+
+    my(@cust_svc)=qsearch('cust_svc',{'pkgnum'=>$pkgnum, 
+                                      'svcpart'=>$svcpart,
+                                     });
+
+    my($enum);
+    for $enum ( 1 .. $pkg_svc{$svcpart} ) {
+
+      my($cust_svc);
+      if ( $cust_svc=shift @cust_svc ) {
+        my($svcnum)=$cust_svc->svcnum;
+        print <<END;
+<TR><TD><A HREF="$uiview{$svcpart}?$svcnum">(View) $svc<A></TD></TR>
+END
+      } else {
+        print <<END;
+<TR>
+  <TD><A HREF="$uiadd{$svcpart}?pkgnum$pkgnum-svcpart$svcpart">
+      (Add) $svc</A>
+   or <A HREF="../misc/link.cgi?pkgnum$pkgnum-svcpart$svcpart">
+      (Link to existing) $svc</A>
+  </TD>
+</TR>
+END
+      }
+
+    }
+    warn "WARNING: Leftover services pkgnum $pkgnum!" if @cust_svc;; 
+  }
+
+  print "</TABLE></CENTER>";
+
+}
+
+#formatting
+print <<END;
+  </BODY>
+</HTML>
+END
+
diff --git a/htdocs/view/svc_domain.cgi b/htdocs/view/svc_domain.cgi
new file mode 100755 (executable)
index 0000000..78ff6ac
--- /dev/null
@@ -0,0 +1,76 @@
+#!/usr/bin/perl -Tw
+#
+# View svc_domain records
+#
+# Usage: svc_domain svcnum
+#        http://server.name/path/svc_domain.cgi?svcnum
+#
+# Note: Should be run setuid freeside as user nobody.
+#
+# ivan@voicenet.com 97-jan-6
+#
+# rewrite ivan@sisd.com 98-mar-14
+#
+# Changes to allow page to work at a relative position in server
+#       bmccane@maxbaud.net     98-apr-3
+
+use strict;
+use CGI::Base qw(:DEFAULT :CGI);
+use FS::UID qw(cgisuidsetup);
+use FS::Record qw(qsearchs);
+
+my($cgi) = new CGI::Base;
+$cgi->get;
+cgisuidsetup($cgi);
+
+#untaint svcnum
+$QUERY_STRING =~ /^(\d+)$/;
+my($svcnum)=$1;
+my($svc_domain)=qsearchs('svc_domain',{'svcnum'=>$svcnum});
+die "Unknown svcnum" unless $svc_domain;
+my($domain)=$svc_domain->domain;
+
+my($cust_svc)=qsearchs('cust_svc',{'svcnum'=>$svcnum});
+my($pkgnum)=$cust_svc->getfield('pkgnum');
+my($cust_pkg,$custnum);
+if ($pkgnum) {
+  $cust_pkg=qsearchs('cust_pkg',{'pkgnum'=>$pkgnum});
+  $custnum=$cust_pkg->getfield('custnum');
+}
+
+my($part_svc)=qsearchs('part_svc',{'svcpart'=> $cust_svc->svcpart } );
+die "Unkonwn svcpart" unless $part_svc;
+
+SendHeaders(); # one guess.
+print <<END;
+<HTML>
+  <HEAD>
+    <TITLE>Domain View</TITLE>
+  </HEAD>
+  <BODY>
+    <CENTER><H1>Domain View</H1>
+    <BASEFONT SIZE=3>
+<CENTER>
+<A HREF="../view/cust_pkg.cgi?$pkgnum">View this package (#$pkgnum)</A> | 
+<A HREF="../view/cust_main.cgi?$custnum">View this customer (#$custnum)</A> | 
+<A HREF="../">Main menu</A></CENTER><BR>
+    <FONT SIZE=+1>Service #$svcnum</FONT>
+    </CENTER>
+END
+
+print "<HR>";
+print "Service: <B>", $part_svc->svc, "</B>";
+print "<HR>";
+
+print qq!Domain name <B>$domain</B>.!;
+print qq!<P><A HREF="http://rs.internic.net/cgi-bin/whois?do+$domain">View whois information.</A>!;
+
+print "<HR>";
+
+       #formatting
+       print <<END;
+
+  </BODY>
+</HTML>
+END
+