summaryrefslogtreecommitdiff
path: root/httemplate/edit/process
diff options
context:
space:
mode:
Diffstat (limited to 'httemplate/edit/process')
-rwxr-xr-xhttemplate/edit/process/REAL_cust_pkg.cgi2
-rwxr-xr-xhttemplate/edit/process/addr_block/add.cgi20
-rwxr-xr-xhttemplate/edit/process/addr_block/allocate.cgi25
-rwxr-xr-xhttemplate/edit/process/addr_block/deallocate.cgi24
-rwxr-xr-xhttemplate/edit/process/addr_block/split.cgi19
-rwxr-xr-xhttemplate/edit/process/cust_main.cgi22
-rwxr-xr-xhttemplate/edit/process/cust_main_county-collapse.cgi4
-rwxr-xr-xhttemplate/edit/process/cust_main_county.cgi21
-rwxr-xr-xhttemplate/edit/process/cust_pkg.cgi25
-rw-r--r--httemplate/edit/process/generic.cgi70
-rwxr-xr-xhttemplate/edit/process/part_bill_event.cgi2
-rwxr-xr-xhttemplate/edit/process/part_pkg.cgi16
-rwxr-xr-xhttemplate/edit/process/part_svc.cgi2
-rw-r--r--httemplate/edit/process/router.cgi67
-rwxr-xr-xhttemplate/edit/process/svc_acct_sm.cgi34
-rw-r--r--httemplate/edit/process/svc_broadband.cgi45
-rwxr-xr-xhttemplate/edit/process/svc_external.cgi29
17 files changed, 364 insertions, 63 deletions
diff --git a/httemplate/edit/process/REAL_cust_pkg.cgi b/httemplate/edit/process/REAL_cust_pkg.cgi
index 2e0352c76..7f5c5e49c 100755
--- a/httemplate/edit/process/REAL_cust_pkg.cgi
+++ b/httemplate/edit/process/REAL_cust_pkg.cgi
@@ -5,6 +5,8 @@ my $old = qsearchs('cust_pkg',{'pkgnum'=>$pkgnum});
my %hash = $old->hash;
$hash{'setup'} = $cgi->param('setup') ? str2time($cgi->param('setup')) : '';
$hash{'bill'} = $cgi->param('bill') ? str2time($cgi->param('bill')) : '';
+$hash{'last_bill'} =
+ $cgi->param('last_bill') ? str2time($cgi->param('last_bill')) : '';
$hash{'expire'} = $cgi->param('expire') ? str2time($cgi->param('expire')) : '';
my $new = new FS::cust_pkg \%hash;
diff --git a/httemplate/edit/process/addr_block/add.cgi b/httemplate/edit/process/addr_block/add.cgi
new file mode 100755
index 000000000..34d799ccd
--- /dev/null
+++ b/httemplate/edit/process/addr_block/add.cgi
@@ -0,0 +1,20 @@
+<%
+
+my $error = '';
+my $ip_gateway = $cgi->param('ip_gateway');
+my $ip_netmask = $cgi->param('ip_netmask');
+
+my $new = new FS::addr_block {
+ ip_gateway => $ip_gateway,
+ ip_netmask => $ip_netmask,
+ routernum => 0 };
+
+$error = $new->insert;
+
+if ( $error ) {
+ $cgi->param('error', $error);
+ print $cgi->redirect(popurl(4). "browse/addr_block.cgi?". $cgi->query_string );
+} else {
+ print $cgi->redirect(popurl(4). "browse/addr_block.cgi");
+}
+%>
diff --git a/httemplate/edit/process/addr_block/allocate.cgi b/httemplate/edit/process/addr_block/allocate.cgi
new file mode 100755
index 000000000..85b0d7a7a
--- /dev/null
+++ b/httemplate/edit/process/addr_block/allocate.cgi
@@ -0,0 +1,25 @@
+<%
+my $error = '';
+my $blocknum = $cgi->param('blocknum');
+my $routernum = $cgi->param('routernum');
+
+my $addr_block = qsearchs('addr_block', { blocknum => $blocknum });
+my $router = qsearchs('router', { routernum => $routernum });
+
+if($addr_block) {
+ if ($router) {
+ $error = $addr_block->allocate($router);
+ } else {
+ $error = "Cannot find router with routernum $routernum";
+ }
+} else {
+ $error = "Cannot find block with blocknum $blocknum";
+}
+
+if ( $error ) {
+ $cgi->param('error', $error);
+ print $cgi->redirect(popurl(4). "browse/addr_block.cgi?" . $cgi->query_string);
+} else {
+ print $cgi->redirect(popurl(4). "browse/addr_block.cgi");
+}
+%>
diff --git a/httemplate/edit/process/addr_block/deallocate.cgi b/httemplate/edit/process/addr_block/deallocate.cgi
new file mode 100755
index 000000000..cfb7ed04d
--- /dev/null
+++ b/httemplate/edit/process/addr_block/deallocate.cgi
@@ -0,0 +1,24 @@
+<%
+my $error = '';
+my $blocknum = $cgi->param('blocknum');
+
+my $addr_block = qsearchs('addr_block', { blocknum => $blocknum });
+
+if($addr_block) {
+ my $router = $addr_block->router;
+ if ($router) {
+ $error = $addr_block->deallocate($router);
+ } else {
+ $error = "Block is not allocated to a router";
+ }
+} else {
+ $error = "Cannot find block with blocknum $blocknum";
+}
+
+if ( $error ) {
+ $cgi->param('error', $error);
+ print $cgi->redirect(popurl(4). "browse/addr_block.cgi?" . $cgi->query_string);
+} else {
+ print $cgi->redirect(popurl(4). "browse/addr_block.cgi");
+}
+%>
diff --git a/httemplate/edit/process/addr_block/split.cgi b/httemplate/edit/process/addr_block/split.cgi
new file mode 100755
index 000000000..bb6d4ba3e
--- /dev/null
+++ b/httemplate/edit/process/addr_block/split.cgi
@@ -0,0 +1,19 @@
+<%
+my $error = '';
+my $blocknum = $cgi->param('blocknum');
+my $addr_block = qsearchs('addr_block', { blocknum => $blocknum });
+
+if ( $addr_block) {
+ $error = $addr_block->split_block;
+} else {
+ $error = "Unknown blocknum: $blocknum";
+}
+
+
+if ( $error ) {
+ $cgi->param('error', $error);
+ print $cgi->redirect(popurl(4). "browse/addr_block.cgi?". $cgi->query_string );
+} else {
+ print $cgi->redirect(popurl(4). "browse/addr_block.cgi");
+}
+%>
diff --git a/httemplate/edit/process/cust_main.cgi b/httemplate/edit/process/cust_main.cgi
index 6ce60d14a..25c346e46 100755
--- a/httemplate/edit/process/cust_main.cgi
+++ b/httemplate/edit/process/cust_main.cgi
@@ -10,16 +10,25 @@ $cgi->param('refnum', (split(/:/, ($cgi->param('refnum'))[0] ))[0] );
my $payby = $cgi->param('payby');
if ( $payby ) {
- $cgi->param('payinfo', $cgi->param( $payby. '_payinfo' ) );
+ if ( $payby eq 'CHEK' || $payby eq 'DCHK' ) {
+ $cgi->param('payinfo',
+ $cgi->param($payby. '_payinfo1'). '@'. $cgi->param($payby. '_payinfo2') );
+ } else {
+ $cgi->param('payinfo', $cgi->param( $payby. '_payinfo' ) );
+ }
$cgi->param('paydate',
- $cgi->param( $payby. '_month' ). '-'. $cgi->param( $payby. '_year' ) );
+ $cgi->param( $payby. '_month' ). '-'. $cgi->param( $payby. '_year' ) );
$cgi->param('payname', $cgi->param( $payby. '_payname' ) );
+ $cgi->param('paycvv', $cgi->param( $payby. '_paycvv' ) )
+ if defined $cgi->param( $payby. '_paycvv' );
}
$cgi->param('otaker', &getotaker );
my @invoicing_list = split( /\s*\,\s*/, $cgi->param('invoicing_list') );
push @invoicing_list, 'POST' if $cgi->param('invoicing_list_POST');
+$cgi->param('invoicing_list', join(',', @invoicing_list) );
+
#create new record object
@@ -46,7 +55,7 @@ if ( $new->custnum eq '' ) {
if ( $cgi->param('pkgpart_svcpart') ) {
my $x = $cgi->param('pkgpart_svcpart');
- $x =~ /^(\d+)_(\d+)$/;
+ $x =~ /^(\d+)_(\d+)$/ or die "illegal pkgpart_svcpart $x\n";
my($pkgpart, $svcpart) = ($1, $2);
#false laziness: copied from FS::cust_pkg::order (which should become a
#FS::cust_main method)
@@ -64,7 +73,7 @@ if ( $new->custnum eq '' ) {
#eslaf
# this should wind up in FS::cust_pkg!
- $error ||= "Agent ". $new->agentnum. " (type ". $agent->typenum. ") can't".
+ $error ||= "Agent ". $new->agentnum. " (type ". $agent->typenum. ") can't ".
"purchase pkgpart ". $pkgpart
#unless $part_pkg{ $pkgpart };
unless $pkgpart_href->{ $pkgpart };
@@ -107,6 +116,11 @@ if ( $new->custnum eq '' ) {
} else { #create old record object
my $old = qsearchs( 'cust_main', { 'custnum' => $new->custnum } );
$error ||= "Old record not found!" unless $old;
+ if ( defined dbdef->table('cust_main')->column('paycvv')
+ && length($old->paycvv)
+ && $new->paycvv =~ /^\s*\*+\s*$/ ) {
+ $new->paycvv($old->paycvv);
+ }
$error ||= $new->replace($old, \@invoicing_list);
}
diff --git a/httemplate/edit/process/cust_main_county-collapse.cgi b/httemplate/edit/process/cust_main_county-collapse.cgi
index 8e67140a8..5da9dea80 100755
--- a/httemplate/edit/process/cust_main_county-collapse.cgi
+++ b/httemplate/edit/process/cust_main_county-collapse.cgi
@@ -3,8 +3,8 @@
my($query) = $cgi->keywords;
$query =~ /^(\d+)$/ or die "Illegal taxnum!";
my $taxnum = $1;
-my $cust_main_county = qsearchs('cust_main_county',{'taxnum'=>$taxnum})
- or die ("Unknown taxnum!");
+my $cust_main_county = qsearchs('cust_main_county', { 'taxnum' => $taxnum } )
+ or die "Unknown taxnum $taxnum";
#really should do this in a .pm & start transaction
diff --git a/httemplate/edit/process/cust_main_county.cgi b/httemplate/edit/process/cust_main_county.cgi
index 990a23919..9287ed150 100755
--- a/httemplate/edit/process/cust_main_county.cgi
+++ b/httemplate/edit/process/cust_main_county.cgi
@@ -2,17 +2,22 @@
foreach ( grep { /^tax\d+$/ } $cgi->param ) {
/^tax(\d+)$/ or die "Illegal form $_!";
- my($taxnum)=$1;
- my($old)=qsearchs('cust_main_county',{'taxnum'=>$taxnum})
+ my $taxnum = $1;
+ my $old = qsearchs('cust_main_county', { 'taxnum' => $taxnum })
or die "Couldn't find taxnum $taxnum!";
- my $exempt_amount = $cgi->param("exempt_amount$taxnum");
- next unless $old->tax ne $cgi->param("tax$taxnum")
- || $old->exempt_amount ne $exempt_amount;
+ next unless $old->tax != $cgi->param("tax$taxnum")
+ || $old->exempt_amount != $cgi->param("exempt_amount$taxnum")
+ || $old->taxname ne $cgi->param("taxname$taxnum")
+ || $old->setuptax ne $cgi->param("setuptax$taxnum")
+ || $old->recurtax ne $cgi->param("recurtax$taxnum");
my %hash = $old->hash;
$hash{tax} = $cgi->param("tax$taxnum");
- $hash{exempt_amount} = $exempt_amount;
- my($new)=new FS::cust_main_county \%hash;
- my($error)=$new->replace($old);
+ $hash{exempt_amount} = $cgi->param("exempt_amount$taxnum");
+ $hash{taxname} = $cgi->param("taxname$taxnum");
+ $hash{setuptax} = $cgi->param("setuptax$taxnum");
+ $hash{recurtax} = $cgi->param("recurtax$taxnum");
+ my $new = new FS::cust_main_county \%hash;
+ my $error = $new->replace($old);
if ( $error ) {
$cgi->param('error', $error);
print $cgi->redirect(popurl(2). "cust_main_county.cgi?". $cgi->query_string );
diff --git a/httemplate/edit/process/cust_pkg.cgi b/httemplate/edit/process/cust_pkg.cgi
index f8c9f5151..df8471c27 100755
--- a/httemplate/edit/process/cust_pkg.cgi
+++ b/httemplate/edit/process/cust_pkg.cgi
@@ -11,16 +11,23 @@ my @remove_pkgnums = map {
$1;
} $cgi->param('remove_pkg');
+my $error_redirect;
my @pkgparts;
-foreach my $pkgpart ( map /^pkg(\d+)$/ ? $1 : (), $cgi->param ) {
- if ( $cgi->param("pkg$pkgpart") =~ /^(\d+)$/ ) {
- my $num_pkgs = $1;
- while ( $num_pkgs-- ) {
- push @pkgparts,$pkgpart;
+if ( $cgi->param('new_pkgpart') =~ /^(\d+)$/ ) { #came from misc/change_pkg.cgi
+ $error_redirect = "misc/change_pkg.cgi";
+ @pkgparts = ($1);
+} else { #came from edit/cust_pkg.cgi
+ $error_redirect = "edit/cust_pkg.cgi";
+ foreach my $pkgpart ( map /^pkg(\d+)$/ ? $1 : (), $cgi->param ) {
+ if ( $cgi->param("pkg$pkgpart") =~ /^(\d+)$/ ) {
+ my $num_pkgs = $1;
+ while ( $num_pkgs-- ) {
+ push @pkgparts,$pkgpart;
+ }
+ } else {
+ $error = "Illegal quantity";
+ last;
}
- } else {
- $error = "Illegal quantity";
- last;
}
}
@@ -28,7 +35,7 @@ $error ||= FS::cust_pkg::order($custnum,\@pkgparts,\@remove_pkgnums);
if ($error) {
$cgi->param('error', $error);
- print $cgi->redirect(popurl(2). "cust_pkg.cgi?". $cgi->query_string );
+ print $cgi->redirect(popurl(3). $error_redirect. '?'. $cgi->query_string );
} else {
print $cgi->redirect(popurl(3). "view/cust_main.cgi?$custnum");
}
diff --git a/httemplate/edit/process/generic.cgi b/httemplate/edit/process/generic.cgi
new file mode 100644
index 000000000..9c54feb1d
--- /dev/null
+++ b/httemplate/edit/process/generic.cgi
@@ -0,0 +1,70 @@
+<%
+
+# Welcome to generic.cgi.
+#
+# This script provides a generic edit/process/ backend for simple table
+# editing. All it knows how to do is take the values entered into
+# the script and insert them into the table specified by $cgi->param('table').
+# If there's an existing record with the same primary key, it will be
+# replaced. (Deletion will be added in the future.)
+#
+# Special cgi params for this script:
+# table: the name of the table to be edited. The script will die horribly
+# if it can't find the table.
+# redirect_ok: URL to be displayed after a successful edit. The value of
+# the record's primary key will be passed as a keyword.
+# Defaults to (freeside root)/view/$table.cgi.
+# redirect_error: URL to be displayed if there's an error. The original
+# query string, plus the error message, will be passed.
+# Defaults to $cgi->referer() (i.e. go back where you
+# came from).
+
+
+use FS::Record qw(qsearchs dbdef);
+use DBIx::DBSchema;
+use DBIx::DBSchema::Table;
+
+
+my $error;
+my $p2 = popurl(2);
+my $p3 = popurl(3);
+my $table = $cgi->param('table');
+my $dbdef = dbdef or die "Cannot fetch dbdef!";
+
+my $dbdef_table = $dbdef->table($table) or die "Cannot fetch schema for $table";
+
+my $pkey = $dbdef_table->primary_key or die "Cannot fetch pkey for $table";
+my $pkey_val = $cgi->param($pkey);
+
+
+#warn "new FS::Record ( $table, (hashref) )";
+my $new = FS::Record::new ( "FS::$table", {
+ map { $_, scalar($cgi->param($_)) } fields($table)
+} );
+
+#warn 'created $new of class '.ref($new);
+
+if($pkey_val and (my $old = qsearchs($table, { $pkey, $pkey_val} ))) {
+ # edit
+ $error = $new->replace($old);
+} else {
+ #add
+ $error = $new->insert;
+ $pkey_val = $new->getfield($pkey);
+ # New records usually don't have their primary keys set until after
+ # they've been checked/inserted, so grab the new $pkey_val so we can
+ # redirect to it.
+}
+
+my $redirect_ok = (($cgi->param('redirect_ok')) ?
+ $cgi->param('redirect_ok') : $p3."browse/generic.cgi?$table");
+my $redirect_error = (($cgi->param('redirect_error')) ?
+ $cgi->param('redirect_error') : $cgi->referer());
+
+if($error) {
+ $cgi->param('error', $error);
+ print $cgi->redirect($redirect_error . '?' . $cgi->query_string);
+} else {
+ print $cgi->redirect($redirect_ok);
+}
+%>
diff --git a/httemplate/edit/process/part_bill_event.cgi b/httemplate/edit/process/part_bill_event.cgi
index 4049ade80..e224bf634 100755
--- a/httemplate/edit/process/part_bill_event.cgi
+++ b/httemplate/edit/process/part_bill_event.cgi
@@ -12,7 +12,7 @@ if ( ! $cgi->param('plan_weight_eventcode') ) {
$error = "Must select an action";
} else {
- $cgi->param('plan_weight_eventcode') =~ /^([\w\-]+):(\d+):(.*)$/
+ $cgi->param('plan_weight_eventcode') =~ /^([\w\-]+):(\d+):(.*)$/s
or die "illegal plan_weight_eventcode:".
$cgi->param('plan_weight_eventcode');
$cgi->param('plan', $1);
diff --git a/httemplate/edit/process/part_pkg.cgi b/httemplate/edit/process/part_pkg.cgi
index d489426f9..7eada7bc8 100755
--- a/httemplate/edit/process/part_pkg.cgi
+++ b/httemplate/edit/process/part_pkg.cgi
@@ -62,16 +62,24 @@ if ( $error ) {
foreach my $part_svc (qsearch('part_svc',{})) {
my $quantity = $cgi->param('pkg_svc'. $part_svc->svcpart) || 0;
+ my $primary_svc =
+ $cgi->param('pkg_svc_primary') == $part_svc->svcpart ? 'Y' : '';
my $old_pkg_svc = qsearchs('pkg_svc', {
'pkgpart' => $pkgpart,
'svcpart' => $part_svc->svcpart,
} );
my $old_quantity = $old_pkg_svc ? $old_pkg_svc->quantity : 0;
- next unless $old_quantity != $quantity; #!here
+ my $old_primary_svc =
+ ( $old_pkg_svc && $old_pkg_svc->dbdef_table->column('primary_svc') )
+ ? $old_pkg_svc->primary_svc
+ : '';
+ next unless $old_quantity != $quantity || $old_primary_svc ne $primary_svc;
+
my $new_pkg_svc = new FS::pkg_svc( {
- 'pkgpart' => $pkgpart,
- 'svcpart' => $part_svc->svcpart,
- 'quantity' => $quantity,
+ 'pkgpart' => $pkgpart,
+ 'svcpart' => $part_svc->svcpart,
+ 'quantity' => $quantity,
+ 'primary_svc' => $primary_svc,
} );
if ( $old_pkg_svc ) {
my $myerror = $new_pkg_svc->replace($old_pkg_svc);
diff --git a/httemplate/edit/process/part_svc.cgi b/httemplate/edit/process/part_svc.cgi
index 859670b17..9633fabdf 100755
--- a/httemplate/edit/process/part_svc.cgi
+++ b/httemplate/edit/process/part_svc.cgi
@@ -17,7 +17,7 @@ my $new = new FS::part_svc ( {
push @fields, 'usergroup' if $svcdb eq 'svc_acct'; #kludge
map { ( $svcdb.'__'.$_, $svcdb.'__'.$_.'_flag' ) } @fields;
} grep defined( $FS::Record::dbdef->table($_) ),
- qw( svc_acct svc_domain svc_acct_sm svc_forward svc_www )
+ qw( svc_acct svc_domain svc_forward svc_www svc_broadband )
)
} );
diff --git a/httemplate/edit/process/router.cgi b/httemplate/edit/process/router.cgi
new file mode 100644
index 000000000..a2fa46dd9
--- /dev/null
+++ b/httemplate/edit/process/router.cgi
@@ -0,0 +1,67 @@
+<%
+
+local $FS::UID::AutoCommit=0;
+
+sub check {
+ my $error = shift;
+ if($error) {
+ $cgi->param('error', $error);
+ print $cgi->redirect(popurl(3) . "edit/router.cgi?". $cgi->query_string);
+ dbh->rollback;
+ exit;
+ }
+}
+
+my $error = '';
+my $routernum = $cgi->param('routernum');
+my $routername = $cgi->param('routername');
+my $old = qsearchs('router', { routernum => $routernum });
+my @old_psr;
+
+my $new = new FS::router {
+ map {
+ ($_, scalar($cgi->param($_)));
+ } fields('router')
+};
+
+if($old) {
+ $error = $new->replace($old);
+} else {
+ $error = $new->insert;
+ $routernum = $new->routernum;
+}
+
+check($error);
+
+if ($old) {
+ @old_psr = $old->part_svc_router;
+ foreach my $psr (@old_psr) {
+ if($cgi->param('svcpart_'.$psr->svcpart) eq 'ON') {
+ # do nothing
+ } else {
+ $error = $psr->delete;
+ }
+ }
+ check($error);
+}
+
+foreach($cgi->param) {
+ if($cgi->param($_) eq 'ON' and /^svcpart_(\d+)$/) {
+ my $svcpart = $1;
+ if(grep {$_->svcpart == $svcpart} @old_psr) {
+ # do nothing
+ } else {
+ my $new_psr = new FS::part_svc_router { svcpart => $svcpart,
+ routernum => $routernum };
+ $error = $new_psr->insert;
+ }
+ check($error);
+ }
+}
+
+
+# Yay, everything worked!
+dbh->commit or die dbh->errstr;
+print $cgi->redirect(popurl(3). "browse/router.cgi");
+
+%>
diff --git a/httemplate/edit/process/svc_acct_sm.cgi b/httemplate/edit/process/svc_acct_sm.cgi
deleted file mode 100755
index 41d03fb92..000000000
--- a/httemplate/edit/process/svc_acct_sm.cgi
+++ /dev/null
@@ -1,34 +0,0 @@
-<%
-
-$cgi->param('svcnum') =~ /^(\d*)$/ or die "Illegal svcnum!";
-my $svcnum =$1;
-
-my $old = qsearchs('svc_acct_sm',{'svcnum'=>$svcnum}) if $svcnum;
-
-#unmunge domsvc and domuid
-#$cgi->param('domsvc',(split(/:/, $cgi->param('domsvc') ))[0] );
-#$cgi->param('domuid',(split(/:/, $cgi->param('domuid') ))[0] );
-
-my $new = new FS::svc_acct_sm ( {
- map {
- ($_, scalar($cgi->param($_)));
- #} qw(svcnum pkgnum svcpart domuser domuid domsvc)
- } ( fields('svc_acct_sm'), qw( pkgnum svcpart ) )
-} );
-
-my $error = '';
-if ( $svcnum ) {
- $error = $new->replace($old);
-} else {
- $error = $new->insert;
- $svcnum = $new->getfield('svcnum');
-}
-
-if ($error) {
- $cgi->param('error', $error);
- print $cgi->redirect(popurl(2). "svc_acct_sm.cgi?". $cgi->query_string );
-} else {
- print $cgi->redirect(popurl(3). "view/svc_acct_sm.cgi?$svcnum");
-}
-
-%>
diff --git a/httemplate/edit/process/svc_broadband.cgi b/httemplate/edit/process/svc_broadband.cgi
new file mode 100644
index 000000000..4912a3a9f
--- /dev/null
+++ b/httemplate/edit/process/svc_broadband.cgi
@@ -0,0 +1,45 @@
+<%
+
+# If it's stupid but it works, it's not stupid.
+# -- U.S. Army
+
+local $FS::UID::AutoCommit = 0;
+my $dbh = FS::UID::dbh;
+
+$cgi->param('svcnum') =~ /^(\d*)$/ or die "Illegal svcnum!";
+my $svcnum = $1;
+
+my $old;
+if ( $svcnum ) {
+ $old = qsearchs('svc_broadband', { 'svcnum' => $svcnum } )
+ or die "fatal: can't find broadband service (svcnum $svcnum)!";
+} else {
+ $old = '';
+}
+
+my $new = new FS::svc_broadband ( {
+ map {
+ ($_, scalar($cgi->param($_)));
+ } ( fields('svc_broadband'), qw( pkgnum svcpart ) )
+} );
+
+my $error;
+if ( $svcnum ) {
+ $error = $new->replace($old);
+} else {
+ $error = $new->insert;
+ $svcnum = $new->svcnum;
+}
+
+
+if ( $error ) {
+ $cgi->param('error', $error);
+ $cgi->param('ip_addr', $new->ip_addr);
+ $dbh->rollback;
+ print $cgi->redirect(popurl(2). "svc_broadband.cgi?". $cgi->query_string );
+} else {
+ $dbh->commit or die $dbh->errstr;
+ print $cgi->redirect(popurl(3). "view/svc_broadband.cgi?" . $svcnum );
+}
+
+%>
diff --git a/httemplate/edit/process/svc_external.cgi b/httemplate/edit/process/svc_external.cgi
new file mode 100755
index 000000000..728cd2189
--- /dev/null
+++ b/httemplate/edit/process/svc_external.cgi
@@ -0,0 +1,29 @@
+<%
+
+$cgi->param('svcnum') =~ /^(\d*)$/ or die "Illegal svcnum!";
+my $svcnum =$1;
+
+my $old = qsearchs('svc_external',{'svcnum'=>$svcnum}) if $svcnum;
+
+my $new = new FS::svc_external ( {
+ map {
+ ($_, scalar($cgi->param($_)));
+ } ( fields('svc_external'), qw( pkgnum svcpart ) )
+} );
+
+my $error = '';
+if ( $svcnum ) {
+ $error = $new->replace($old);
+} else {
+ $error = $new->insert;
+ $svcnum = $new->getfield('svcnum');
+}
+
+if ($error) {
+ $cgi->param('error', $error);
+ print $cgi->redirect(popurl(2). "svc_external.cgi?". $cgi->query_string );
+} else {
+ print $cgi->redirect(popurl(3). "view/svc_external.cgi?$svcnum");
+}
+
+%>