diff options
Diffstat (limited to 'httemplate/edit/process')
71 files changed, 3029 insertions, 0 deletions
diff --git a/httemplate/edit/process/REAL_cust_pkg.cgi b/httemplate/edit/process/REAL_cust_pkg.cgi new file mode 100755 index 000000000..ebcb7e4ba --- /dev/null +++ b/httemplate/edit/process/REAL_cust_pkg.cgi @@ -0,0 +1,36 @@ +%if ( $error ) { +% $cgi->param('error', $error); +<% $cgi->redirect(popurl(2). "REAL_cust_pkg.cgi?". $cgi->query_string ) %> +%} else { +% my $custnum = $new->custnum; +<% $cgi->redirect(popurl(3). "view/cust_main.cgi?$custnum#cust_pkg$pkgnum" ) %> +%} +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Edit customer package dates'); + +my $pkgnum = $cgi->param('pkgnum') or die; +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{'adjourn'} = $cgi->param('adjourn') ? str2time($cgi->param('adjourn')) : ''; +$hash{'expire'} = $cgi->param('expire') ? str2time($cgi->param('expire')) : ''; + +my $new; +my $error; +if ( $hash{'bill'} != $old->bill # if the next bill date was changed + && $hash{'bill'} < time # to a date in the past + && ! $cgi->param('bill_areyousure') # and it wasn't confirmed + ) +{ + $error = '_bill_areyousure'; +} else { + $new = new FS::cust_pkg \%hash; + $error = $new->replace($old); +} + +</%init> diff --git a/httemplate/edit/process/access_group.html b/httemplate/edit/process/access_group.html new file mode 100644 index 000000000..ab25cb3a2 --- /dev/null +++ b/httemplate/edit/process/access_group.html @@ -0,0 +1,28 @@ +% if ( $conf->exists('disable_acl_changes') ) { + ACL changes disabled in public demo. +% } else { +<% include( 'elements/process.html', + 'table' => 'access_group', + 'viewall_dir' => 'browse', + 'process_m2m' => { 'link_table' => 'access_groupagent', + 'target_table' => 'agent', + }, + 'process_m2name' => { + 'link_table' => 'access_right', + 'link_static' => { 'righttype' => 'FS::access_group', }, + 'num_col' => 'rightobjnum', + 'name_col' => 'rightname', + 'names_list' => [ FS::AccessRight->rights() ], + 'param_style' => 'link_table.value checkboxes', + }, + ) +%> +% } +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $conf = new FS::Conf; + +</%init> diff --git a/httemplate/edit/process/access_user.html b/httemplate/edit/process/access_user.html new file mode 100644 index 000000000..ca6bb603f --- /dev/null +++ b/httemplate/edit/process/access_user.html @@ -0,0 +1,21 @@ +% if ( $cgi->param('_password') ne $cgi->param('_password2') ) { +% $cgi->param('error', "The passwords do not match"); +% print $cgi->redirect(popurl(2) . "access_user.html?" . $cgi->query_string); +% } else { +<% include( 'elements/process.html', + 'table' => 'access_user', + 'viewall_dir' => 'browse', + 'copy_on_empty' => [ '_password' ], + 'clear_on_error' => [ '_password', '_password2' ], + 'process_m2m' => { 'link_table' => 'access_usergroup', + 'target_table' => 'access_group', + }, + ) +%> +% } +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +</%init> diff --git a/httemplate/edit/process/addr_block/add.cgi b/httemplate/edit/process/addr_block/add.cgi new file mode 100755 index 000000000..39d6348ce --- /dev/null +++ b/httemplate/edit/process/addr_block/add.cgi @@ -0,0 +1,20 @@ +<% include( '../elements/process.html', + 'table' => 'addr_block', + 'redirect' => popurl(4). 'browse/addr_block.cgi?dummy=', + 'error_redirect' => popurl(4). 'browse/addr_block.cgi?', + 'agent_virt' => 1, + 'agent_null_right' => 'Broadband global configuration', + + ) +%> +<%init> + +my $curuser = $FS::CurrentUser::CurrentUser; +die "access denied" + unless $curuser->access_right('Broadband configuration') + || $curuser->access_right('Broadband global configuration'); + +$cgi->param('routernum', 0) # in FS::addr_block::check instead? + unless $cgi->param('routernum'); + +</%init> diff --git a/httemplate/edit/process/addr_block/allocate.cgi b/httemplate/edit/process/addr_block/allocate.cgi new file mode 100755 index 000000000..40d04b369 --- /dev/null +++ b/httemplate/edit/process/addr_block/allocate.cgi @@ -0,0 +1,16 @@ +<% include( '../elements/process.html', + 'table' => 'addr_block', + 'copy_on_empty' => [ fields 'addr_block' ], + 'error_redirect' => popurl(3). 'allocate.html?', + 'popup_reload' => 'Block allocated', + ) +%> +<%init> + +my $conf = new FS::Conf; +my $curuser = $FS::CurrentUser::CurrentUser; +die "access denied" + unless $curuser->access_right('Broadband configuration') + || $curuser->access_right('Broadband global configuration'); + +</%init> diff --git a/httemplate/edit/process/addr_block/deallocate.cgi b/httemplate/edit/process/addr_block/deallocate.cgi new file mode 100755 index 000000000..128824ec7 --- /dev/null +++ b/httemplate/edit/process/addr_block/deallocate.cgi @@ -0,0 +1,20 @@ +<% include( '../elements/process.html', + 'table' => 'addr_block', + 'copy_on_empty' => [ grep { $_ ne 'routernum' } + fields 'addr_block' ], + 'redirect' => popurl(4). 'browse/addr_block.cgi?', + 'error_redirect' => popurl(4). 'browse/addr_block.cgi?', + 'agent_virt' => 1, + 'agent_null_right' => 'Broadband global configuration', + ) +%> +<%init> + +my $conf = new FS::Conf; +my $curuser = $FS::CurrentUser::CurrentUser; +die "access denied" + unless $curuser->access_right('Broadband configuration') + || $curuser->access_right('Broadband global configuration'); + +$cgi->param('routernum', 0); # just to be explicit about what we are doing +</%init> diff --git a/httemplate/edit/process/addr_block/manual_flag.cgi b/httemplate/edit/process/addr_block/manual_flag.cgi new file mode 100755 index 000000000..dc0cbbbf5 --- /dev/null +++ b/httemplate/edit/process/addr_block/manual_flag.cgi @@ -0,0 +1,30 @@ +<% $cgi->redirect(popurl(4). "browse/addr_block.cgi?". $cgi->query_string ) %> +<%init> + +my $curuser = $FS::CurrentUser::CurrentUser; + +die "access denied" + unless $curuser->access_right('Broadband configuration') + || $curuser->access_right('Broadband global configuration'); + +my $error = ''; +$cgi->param('blocknum') =~ /^(\d+)$/ or die "invalid blocknum"; +my $blocknum = $1; + +my $addr_block = qsearchs({ 'table' => 'addr_block', + 'hashref' => { blocknum => $blocknum }, + 'extra_sql' => ' AND '. $curuser->agentnums_sql( + 'null_right' => 'Broadband global configuration' + ), + }) + or $error = "Unknown blocknum: $blocknum"; + +$addr_block->manual_flag($cgi->param('manual_flag')) + unless $error; + +$error ||= $addr_block->replace; + +$cgi->param('error', $error) + if $error; + +</%init> diff --git a/httemplate/edit/process/addr_block/split.cgi b/httemplate/edit/process/addr_block/split.cgi new file mode 100755 index 000000000..045fd30de --- /dev/null +++ b/httemplate/edit/process/addr_block/split.cgi @@ -0,0 +1,27 @@ +<% $cgi->redirect(popurl(4). "browse/addr_block.cgi?". $cgi->query_string ) %> +<%init> + +my $curuser = $FS::CurrentUser::CurrentUser; + +die "access denied" + unless $curuser->access_right('Broadband configuration') + || $curuser->access_right('Broadband global configuration'); + +my $error = ''; +$cgi->param('blocknum') =~ /^(\d+)$/ or die "invalid blocknum"; +my $blocknum = $1; + +my $addr_block = qsearchs({ 'table' => 'addr_block', + 'hashref' => { blocknum => $blocknum }, + 'extra_sql' => ' AND '. $curuser->agentnums_sql( + 'null_right' => 'Broadband global configuration' + ), + }) + or $error = "Unknown blocknum: $blocknum"; + +$error ||= $addr_block->split_block; + +$cgi->param('error', $error) + if $error; + +</%init> diff --git a/httemplate/edit/process/agent.cgi b/httemplate/edit/process/agent.cgi new file mode 100755 index 000000000..3cdf40c9b --- /dev/null +++ b/httemplate/edit/process/agent.cgi @@ -0,0 +1,16 @@ +<% include( 'elements/process.html', + 'table' => 'agent', + 'viewall_dir' => 'browse', + 'viewall_ext' => 'cgi', + 'process_m2m' => { 'link_table' => 'access_groupagent', + 'target_table' => 'access_group', + }, + 'edit_ext' => 'cgi', + ) +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +</%init> diff --git a/httemplate/edit/process/agent_payment_gateway.html b/httemplate/edit/process/agent_payment_gateway.html new file mode 100644 index 000000000..5b5fd948a --- /dev/null +++ b/httemplate/edit/process/agent_payment_gateway.html @@ -0,0 +1,29 @@ +<% $cgi->redirect(popurl(3). "browse/agent.cgi") %> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +$cgi->param('agentnum') =~ /(\d+)$/ or die "illegal agentnum"; +my $agent = qsearchs('agent', { 'agentnum' => $1 } ); +die "agentnum $1 not found" unless $agent; + +#my $old + +my @new = map { + my $cardtype = $_; + new FS::agent_payment_gateway { + ( map { $_ => scalar($cgi->param($_)) } + fields('agent_payment_gateway') + ), + 'cardtype' => $cardtype, + }; + } + $cgi->param('cardtype'); + +foreach my $new (@new) { + my $error = $new->insert; + die $error if $error; +} + +</%init> diff --git a/httemplate/edit/process/agent_type.cgi b/httemplate/edit/process/agent_type.cgi new file mode 100755 index 000000000..ad5963b31 --- /dev/null +++ b/httemplate/edit/process/agent_type.cgi @@ -0,0 +1,35 @@ +%if ( $error ) { +% $cgi->param('error', $error); +<% $cgi->redirect(popurl(2). "agent_type.cgi?". $cgi->query_string ) %> +%} else { +<% $cgi->redirect(popurl(3). "browse/agent_type.cgi") %> +%} +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $typenum = $cgi->param('typenum'); +my $old = qsearchs('agent_type',{'typenum'=>$typenum}) if $typenum; + +my $new = new FS::agent_type ( { + map { + $_, scalar($cgi->param($_)); + } fields('agent_type') +} ); + +my $error; +if ( $typenum ) { + $error = $new->replace($old); +} else { + $error = $new->insert; + $typenum = $new->getfield('typenum'); +} + + $error ||= $new->process_m2m( + 'link_table' => 'type_pkgs', + 'target_table' => 'part_pkg', + 'params' => scalar($cgi->Vars) + ); + +</%init> diff --git a/httemplate/edit/process/bulk-cust_main_county.html b/httemplate/edit/process/bulk-cust_main_county.html new file mode 100644 index 000000000..e05192e96 --- /dev/null +++ b/httemplate/edit/process/bulk-cust_main_county.html @@ -0,0 +1,63 @@ +% if ( $error ) { #better to redirect back to +%# <% $cgi->redirect("$url?". $cgi->query_string ) %> + <% include('/elements/header-popup.html', 'Error adding taxes' ) %> + + <FONT SIZE="+1" COLOR="#ff0000">Error: <% $error |h %></FONT> + <BR><BR> + + </BODY> + </HTML> + +% } else { + <% include('/elements/header-popup.html', 'Taxes added') %> + + <SCRIPT TYPE="text/javascript"> + window.top.location.reload(); + </SCRIPT> + + </BODY> + </HTML> +% } +<%init> + +$cgi->param('taxnum') =~ /^([\d,]+)$/ + or die 'Guru Meditation #69'; #??? should have been passed in +my @taxnum = split(',', $1); + +my $error = ''; +foreach my $taxnum ( @taxnum ) { + + my $cust_main_county = qsearchs('cust_main_county', { 'taxnum' => $taxnum } ) + or die "unknown taxnum: $taxnum"; + + if ( $cust_main_county->tax == 0 ) { #let's replace + + foreach (qw( taxname tax exempt_amount setuptax recurtax )) { + $cust_main_county->set( $_ => scalar($cgi->param($_)) ) + } + + $error = $cust_main_county->replace and last; + + } else { #let's insert a new record + + my $new = + new FS::cust_main_county { + ( map { $_ => scalar($cgi->param($_)) } + qw( taxname tax exempt_amount setuptax recurtax ) + ), + ( map { $_ => $cust_main_county->get($_) } + qw( country state county taxclass ) + ) + }; + + $error = $new->insert and last; + + } + +} + +if ( $error ) { + $cgi->param('error', $error); +} + +</%init> diff --git a/httemplate/edit/process/bulk-cust_svc.cgi b/httemplate/edit/process/bulk-cust_svc.cgi new file mode 100644 index 000000000..313b061ff --- /dev/null +++ b/httemplate/edit/process/bulk-cust_svc.cgi @@ -0,0 +1,9 @@ +<% $server->process %> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $server = new FS::UI::Web::JSRPC 'FS::part_svc::process_bulk_cust_svc', $cgi; + +</%init> diff --git a/httemplate/edit/process/change-cust_pkg.html b/httemplate/edit/process/change-cust_pkg.html new file mode 100644 index 000000000..7356e6122 --- /dev/null +++ b/httemplate/edit/process/change-cust_pkg.html @@ -0,0 +1,46 @@ +% if ($error) { +% $cgi->param('error', $error); +% $cgi->redirect(popurl(3). 'misc/change_pkg.cgi?'. $cgi->query_string ); +% } else { + + <% header("Package changed") %> + <SCRIPT TYPE="text/javascript"> + window.top.location.reload(); + </SCRIPT> + </BODY> + </HTML> + +% } +<%init> + +my $curuser = $FS::CurrentUser::CurrentUser; + +die "access denied" + unless $curuser->access_right('Change customer package'); + +my $cust_pkg = qsearchs({ + #'select' => 'cust_pkg.*', + 'table' => 'cust_pkg', + 'addl_from' => 'LEFT JOIN cust_main USING ( custnum )', + 'hashref' => { 'pkgnum' => scalar($cgi->param('pkgnum')), }, + 'extra_sql' => ' AND '. $curuser->agentnums_sql, +}); +die 'unknown pkgnum' unless $cust_pkg; + +my %change = map { $_ => scalar($cgi->param($_)) } + qw( locationnum pkgpart ); + +if ( $cgi->param('locationnum') == -1 ) { + my $cust_location = new FS::cust_location { + 'custnum' => $cust_pkg->custnum, + map { $_ => scalar($cgi->param($_)) } + qw( address1 address2 city county state zip country ) + }; + $change{'cust_location'} = $cust_location; +} + +my $pkg_or_error = $cust_pkg->change( \%change ); + +my $error = ref($pkg_or_error) ? '' : $pkg_or_error; + +</%init> diff --git a/httemplate/edit/process/cust_bill_pay.cgi b/httemplate/edit/process/cust_bill_pay.cgi new file mode 100755 index 000000000..2845d3233 --- /dev/null +++ b/httemplate/edit/process/cust_bill_pay.cgi @@ -0,0 +1,13 @@ +<% include('elements/ApplicationCommon.html', + 'error_redirect' => 'cust_bill_pay.cgi', + 'src_table' => 'cust_pay', + 'src_thing' => 'payment', + 'link_table' => 'cust_bill_pay', + ) +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Apply payment'); + +</%init> diff --git a/httemplate/edit/process/cust_credit.cgi b/httemplate/edit/process/cust_credit.cgi new file mode 100755 index 000000000..8715ad61e --- /dev/null +++ b/httemplate/edit/process/cust_credit.cgi @@ -0,0 +1,63 @@ +%if ( $error ) { +% $cgi->param('reasonnum', $reasonnum); +% $cgi->param('error', $error); +% $dbh->rollback if $oldAutoCommit; +% +<% $cgi->redirect(popurl(2). "cust_credit.cgi?". $cgi->query_string ) %> +% +%} else { +% +% if ( $cgi->param('apply') eq 'yes' ) { +% my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum }) +% or die "unknown custnum $custnum"; +% $cust_main->apply_credits; +% } +% #print $cgi->redirect(popurl(3). "view/cust_main.cgi?$custnum"); +% +% $dbh->commit or die $dbh->errstr if $oldAutoCommit; +% +<% header('Credit sucessful') %> + <SCRIPT TYPE="text/javascript"> + window.top.location.reload(); + </SCRIPT> + + </BODY></HTML> +% } +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Post credit'); + +$cgi->param('custnum') =~ /^(\d*)$/ or die "Illegal custnum!"; +my $custnum = $1; + +$cgi->param('reasonnum') =~ /^(-?\d+)$/ or die "Illegal reasonnum"; +my $reasonnum = $1; + +my $oldAutoCommit = $FS::UID::AutoCommit; +local $FS::UID::AutoCommit = 0; +my $dbh = dbh; + +my $error = ''; +if ($reasonnum == -1) { + + $error = 'Enter a new reason (or select an existing one)' + unless $cgi->param('newreasonnum') !~ /^\s*$/; + my $reason = new FS::reason({ 'reason_type' => $cgi->param('newreasonnumT'), + 'reason' => $cgi->param('newreasonnum'), + }); + $error ||= $reason->insert; + $cgi->param('reasonnum', $reason->reasonnum) + unless $error; +} + +unless ($error) { + my $new = new FS::cust_credit ( { + map { + $_, scalar($cgi->param($_)); + } fields('cust_credit') + } ); + $error = $new->insert; +} + +</%init> diff --git a/httemplate/edit/process/cust_credit_bill.cgi b/httemplate/edit/process/cust_credit_bill.cgi new file mode 100755 index 000000000..c0f34ae5b --- /dev/null +++ b/httemplate/edit/process/cust_credit_bill.cgi @@ -0,0 +1,13 @@ +<% include('elements/ApplicationCommon.html', + 'error_redirect' => 'cust_credit_bill.cgi', + 'src_table' => 'cust_credit', + 'src_thing' => 'credit', + 'link_table' => 'cust_credit_bill', + ) +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Apply credit'); + +</%init> diff --git a/httemplate/edit/process/cust_credit_refund.cgi b/httemplate/edit/process/cust_credit_refund.cgi new file mode 100755 index 000000000..88420f8ab --- /dev/null +++ b/httemplate/edit/process/cust_credit_refund.cgi @@ -0,0 +1,13 @@ +<% include('elements/ApplicationCommon.html', + 'error_redirect' => 'cust_credit_refund.cgi', + 'src_table' => 'cust_credit', + 'src_thing' => 'credit', + 'link_table' => 'cust_credit_refund', + ) +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Apply credit'); + +</%init> diff --git a/httemplate/edit/process/cust_main.cgi b/httemplate/edit/process/cust_main.cgi new file mode 100755 index 000000000..097d38204 --- /dev/null +++ b/httemplate/edit/process/cust_main.cgi @@ -0,0 +1,210 @@ +% if ( $error ) { +% $cgi->param('error', $error); +% +<% $cgi->redirect(popurl(2). "cust_main.cgi?". $cgi->query_string ) %> +% +% } else { +% +<% $cgi->redirect(popurl(3). "view/cust_main.cgi?". $new->custnum) %> +% +% } +<%once> + +my $me = '[edit/process/cust_main.cgi]'; +my $DEBUG = 0; + +</%once> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Edit customer'); + +my $error = ''; + +#unmunge stuff + +$cgi->param('tax','') unless defined $cgi->param('tax'); + +$cgi->param('refnum', (split(/:/, ($cgi->param('refnum'))[0] ))[0] ); + +#my $payby = $cgi->param('payby'); +my $payby = $cgi->param('select'); # XXX key + +my %noauto = ( + 'CARD' => 'DCRD', + 'CHEK' => 'DCHK', +); +$payby = $noauto{$payby} + if ! $cgi->param('payauto') && exists $noauto{$payby}; + +$cgi->param('payby', $payby); + +if ( $payby ) { + if ( $payby eq 'CHEK' || $payby eq 'DCHK' ) { + $cgi->param('payinfo', + $cgi->param('payinfo1'). '@'. $cgi->param('payinfo2') ); + } + $cgi->param('paydate', + $cgi->param( 'exp_month' ). '-'. $cgi->param( 'exp_year' ) ); +} + +my @invoicing_list = split( /\s*\,\s*/, $cgi->param('invoicing_list') ); +push @invoicing_list, 'POST' if $cgi->param('invoicing_list_POST'); +push @invoicing_list, 'FAX' if $cgi->param('invoicing_list_FAX'); +$cgi->param('invoicing_list', join(',', @invoicing_list) ); + + +#create new record object + +my $new = new FS::cust_main ( { + map { + $_, scalar($cgi->param($_)) +# } qw(custnum agentnum last first ss company address1 address2 city county +# state zip daytime night fax payby payinfo paydate payname tax +# otaker refnum) + } fields('cust_main') +} ); + +if ( defined($cgi->param('same')) && $cgi->param('same') eq "Y" ) { + $new->setfield("ship_$_", '') foreach qw( + last first company address1 address2 city county state zip + country daytime night fax + ); +} + +if ( $cgi->param('birthdate') && $cgi->param('birthdate') =~ /^([ 0-9\-\/]{0,10})$/) { + my $conf = new FS::Conf; + my $format = $conf->config('date_format') || "%m/%d/%Y"; + my $parser = DateTime::Format::Strptime->new(pattern => $format, + time_zone => 'floating', + ); + my $dt = $parser->parse_datetime($1); + if ($dt) { + $new->setfield('birthdate', $dt->epoch); + $cgi->param('birthdate', $dt->epoch); + } else { +# $error ||= $cgi->param('birthdate') . " is an invalid birthdate:" . $parser->errmsg; + $error ||= "Invalid birthdate: " . $cgi->param('birthdate') . "."; + $cgi->param('birthdate', ''); + } +} + +$new->setfield('paid', $cgi->param('paid') ) + if $cgi->param('paid'); + +#perhaps this stuff should go to cust_main.pm +my $cust_pkg = ''; +my $svc_acct = ''; +if ( $new->custnum eq '' ) { + + if ( $cgi->param('pkgpart_svcpart') ) { + my $x = $cgi->param('pkgpart_svcpart'); + $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) + my(%part_pkg); + # generate %part_pkg + # $part_pkg{$pkgpart} is true iff $custnum may purchase $pkgpart + my $agent = qsearchs('agent',{'agentnum'=> $new->agentnum }); + #my($type_pkgs); + #foreach $type_pkgs ( qsearch('type_pkgs',{'typenum'=> $agent->typenum }) ) { + # my($pkgpart)=$type_pkgs->pkgpart; + # $part_pkg{$pkgpart}++; + #} + # $pkgpart_href->{PKGPART} is true iff $custnum may purchase $pkgpart + my $pkgpart_href = $agent->pkgpart_hashref; + #eslaf + + # this should wind up in FS::cust_pkg! + $error ||= "Agent ". $new->agentnum. " (type ". $agent->typenum. ") can't ". + "purchase pkgpart ". $pkgpart + #unless $part_pkg{ $pkgpart }; + unless $pkgpart_href->{ $pkgpart }; + + $cust_pkg = new FS::cust_pkg ( { + #later 'custnum' => $custnum, + 'pkgpart' => $pkgpart, + } ); + #$error ||= $cust_pkg->check; + + #$cust_svc = new FS::cust_svc ( { 'svcpart' => $svcpart } ); + + #$error ||= $cust_svc->check; + + my %svc_acct = ( + 'svcpart' => $svcpart, + 'username' => $cgi->param('username'), + '_password' => $cgi->param('_password'), + 'popnum' => $cgi->param('popnum'), + ); + $svc_acct{'domsvc'} = $cgi->param('domsvc') + if $cgi->param('domsvc'); + + $svc_acct = new FS::svc_acct \%svc_acct; + + #and just in case you were silly + $svc_acct->svcpart($svcpart); + $svc_acct->username($cgi->param('username')); + $svc_acct->_password($cgi->param('_password')); + $svc_acct->popnum($cgi->param('popnum')); + + #$error ||= $svc_acct->check; + + } elsif ( $cgi->param('username') ) { #good thing to catch + $error = "Can't assign username without a package!"; + } + + use Tie::RefHash; + tie my %hash, 'Tie::RefHash'; + %hash = ( $cust_pkg => [ $svc_acct ] ) if $cust_pkg; + $error ||= $new->insert( \%hash, \@invoicing_list ); + + my $conf = new FS::Conf; + if ( $conf->exists('backend-realtime') && ! $error ) { + + my $berror = $new->bill + || $new->apply_payments_and_credits + || $new->collect( 'realtime' => 1 ); + warn "Warning, error billing during backend-realtime: $berror" if $berror; + + } + +} else { #create old record object + + my $old = qsearchs( 'cust_main', { 'custnum' => $new->custnum } ); + $error ||= "Old record not found!" unless $old; + if ( length($old->paycvv) && $new->paycvv =~ /^\s*\*+\s*$/ ) { + $new->paycvv($old->paycvv); + } + if ($new->ss =~ /xx/) { + $new->ss($old->ss); + } + if ($new->stateid =~ /^xxx/) { + $new->stateid($old->stateid); + } + if ($new->payby =~ /^(CARD|DCRD)$/ && $new->payinfo =~ /xx/) { + $new->payinfo($old->payinfo); + } elsif ($new->payby =~ /^(CHEK|DCHK)$/ && $new->payinfo =~ /xx/) { + #fix for #3085 "edit of customer's routing code only surprisingly causes + #nothing to happen... + # this probably won't do the right thing when we don't have the + # public key (can't actually get the real $old->payinfo) + my($new_account, $new_aba) = split('@', $new->payinfo); + my($old_account, $old_aba) = split('@', $old->payinfo); + $new_account = $old_account if $new_account =~ /xx/; + $new_aba = $old_aba if $new_aba =~ /xx/; + $new->payinfo($new_account.'@'.$new_aba); + } + + warn "$me calling $new -> replace( $old, \ @invoicing_list )" if $DEBUG; + local($FS::cust_main::DEBUG) = $DEBUG if $DEBUG; + local($FS::Record::DEBUG) = $DEBUG if $DEBUG; + + $error ||= $new->replace($old, \@invoicing_list); + + warn "$me returned from replace" if $DEBUG; + +} + +</%init> diff --git a/httemplate/edit/process/cust_main_county-collapse.cgi b/httemplate/edit/process/cust_main_county-collapse.cgi new file mode 100755 index 000000000..a917825ce --- /dev/null +++ b/httemplate/edit/process/cust_main_county-collapse.cgi @@ -0,0 +1,44 @@ +% +% +%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 $taxnum"; +% +%#really should do this in a .pm & start transaction +% +%foreach my $delete ( qsearch('cust_main_county', { +% 'country' => $cust_main_county->country, +% 'state' => $cust_main_county->state +% } ) ) { +%# unless ( qsearch('cust_main',{ +%# 'state' => $cust_main_county->getfield('state'), +%# 'county' => $cust_main_county->getfield('county'), +%# 'country' => $cust_main_county->getfield('country'), +%# } ) ) { +% my $error = $delete->delete; +% die $error if $error; +%# } else { +% #should really fix the $cust_main record +%# } +% +%} +% +%$cust_main_county->taxnum(''); +%$cust_main_county->county(''); +%my $error = $cust_main_county->insert; +%die $error if $error; +% +%print $cgi->redirect(popurl(3). "browse/cust_main_county.cgi"); +% +% +<%init> + +#this isn't actually linked from anywhere just now, but it will be again soon + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + + +</%init> diff --git a/httemplate/edit/process/cust_main_county-expand.cgi b/httemplate/edit/process/cust_main_county-expand.cgi new file mode 100755 index 000000000..04533a539 --- /dev/null +++ b/httemplate/edit/process/cust_main_county-expand.cgi @@ -0,0 +1,78 @@ +<% include('/elements/header-popup.html', 'Addition successful' ) %> + +<SCRIPT TYPE="text/javascript"> + window.top.location.reload(); +</SCRIPT> + +</BODY> +</HTML> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +$cgi->param('taxnum') =~ /^(\d+)$/ or die "Illegal taxnum!"; +my $taxnum = $1; +my $cust_main_county = qsearchs('cust_main_county',{'taxnum'=>$taxnum}) + or die ("Unknown taxnum!"); + +my @expansion; +if ( $cgi->param('taxclass') ) { + my $sth = dbh->prepare('SELECT taxclass FROM part_pkg_taxclass') + or die dbh->errstr; + $sth->execute or die $sth->errstr; + @expansion = map $_->[0], @{$sth->fetchall_arrayref}; + die "no taxclasses - add one first" unless @expansion;#XXX better err handling +} else { + @expansion = split /[\n\r]{1,2}/, $cgi->param('expansion'); + + #warn scalar(@expansion); + #warn "$_: $expansion[$_]\n" foreach (0..$#expansion); + + @expansion=map { + unless ( /^\s*([\w \!\@\#\$\%\&\(\)\-\+\;\:\'\"\,\.\?\/\=\[\]]+)\s*$/ ) { + $cgi->param('error', "Illegal item in expansion: $_"); + print $cgi->redirect(popurl(2). "cust_main_county-expand.cgi?". $cgi->query_string ); + myexit(); + } + $1; + } @expansion; + +} + +foreach ( @expansion) { + my(%hash)=$cust_main_county->hash; + my($new)=new FS::cust_main_county \%hash; + $new->setfield('taxnum',''); + if ( $cgi->param('taxclass') ) { + $new->setfield('taxclass', $_); + } elsif ( ! $cust_main_county->state ) { + $new->setfield('state',$_); + } else { + $new->setfield('county',$_); + } + my $error = $new->insert; + die $error if $error; +} + +unless ( qsearch( 'cust_main', { + 'state' => $cust_main_county->state, + 'county' => $cust_main_county->county, + 'country' => $cust_main_county->country, + } ) + || ! @expansion +) { + my $error = $cust_main_county->delete; + die $error if $error; +} + +if ( $cgi->param('taxclass') ) { + print $cgi->redirect(popurl(3). "browse/cust_main_county.cgi?". + 'state='. uri_escape($cust_main_county->state ).';'. + 'county='. uri_escape($cust_main_county->county ).';'. + 'country='. uri_escape($cust_main_county->country) + ); + myexit; +} + +</%init> diff --git a/httemplate/edit/process/cust_main_county.html b/httemplate/edit/process/cust_main_county.html new file mode 100644 index 000000000..cb56166c8 --- /dev/null +++ b/httemplate/edit/process/cust_main_county.html @@ -0,0 +1,13 @@ +<% include( 'elements/process.html', + 'table' => 'cust_main_county', + 'popup_reload' => 'Tax changed', #a popup "parent reload" for now + #someday change the individual element and go away instead + ) +%> +<%init> + +my $conf = new FS::Conf; +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +</%init> diff --git a/httemplate/edit/process/cust_main_note.cgi b/httemplate/edit/process/cust_main_note.cgi new file mode 100755 index 000000000..5127c72d1 --- /dev/null +++ b/httemplate/edit/process/cust_main_note.cgi @@ -0,0 +1,54 @@ +%if ($error) { +% $cgi->param('error', $error); +<% $cgi->redirect(popurl(2). 'cust_main_note.cgi?'. $cgi->query_string ) %> +%} else { +<% header('Note ' . ($notenum ? 'updated' : 'added') ) %> + <SCRIPT TYPE="text/javascript"> + window.top.location.reload(); + </SCRIPT> + </BODY></HTML> +% } +<%init> + +$cgi->param('custnum') =~ /^(\d+)$/ + or die "Illegal custnum: ". $cgi->param('custnum'); +my $custnum = $1; + +$cgi->param('notenum') =~ /^(\d*)$/ + or die "Illegal notenum: ". $cgi->param('notenum'); +my $notenum = $1; + +my $otaker = $FS::CurrentUser::CurrentUser->name; +$otaker = $FS::CurrentUser::CurrentUser->username + if ($otaker eq "User, Legacy"); + +my $new = new FS::cust_main_note ( { + notenum => $notenum, + custnum => $custnum, + _date => time, + otaker => $otaker, + comments => $cgi->param('comment'), +} ); + +my $error; +if ($notenum) { + + die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Edit customer note'); + + my $old = qsearchs('cust_main_note', { 'notenum' => $notenum }); + $error = "No such note: $notenum" unless $old; + unless ($error) { + map { $new->$_($old->$_) } ('_date', 'otaker'); + $error = $new->replace($old); + } + +} else { + + die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Add customer note'); + + $error = $new->insert; +} + +</%init> diff --git a/httemplate/edit/process/cust_pay.cgi b/httemplate/edit/process/cust_pay.cgi new file mode 100755 index 000000000..647f6fc6c --- /dev/null +++ b/httemplate/edit/process/cust_pay.cgi @@ -0,0 +1,55 @@ +%if ($error) { +% $cgi->param('error', $error); +<% $cgi->redirect(popurl(2). 'cust_pay.cgi?'. $cgi->query_string ) %> +%} elsif ( $field eq 'invnum' ) { +<% $cgi->redirect(popurl(3). "view/cust_bill.cgi?$linknum") %> +%} elsif ( $field eq 'custnum' ) { +% if ( $cgi->param('apply') eq 'yes' ) { +% my $cust_main = qsearchs('cust_main', { 'custnum' => $linknum }) +% or die "unknown custnum $linknum"; +% $cust_main->apply_payments; +% } +% if ( $link eq 'popup' ) { +% +<% header('Payment entered') %> + <SCRIPT TYPE="text/javascript"> + window.top.location.reload(); + </SCRIPT> + + </BODY></HTML> +% +% } elsif ( $link eq 'custnum' ) { +<% $cgi->redirect(popurl(3). "view/cust_main.cgi?$linknum") %> +% } else { +% die "unknown link $link"; +% } +% +%} +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Post payment'); + +$cgi->param('linknum') =~ /^(\d+)$/ + or die "Illegal linknum: ". $cgi->param('linknum'); +my $linknum = $1; + +$cgi->param('link') =~ /^(custnum|invnum|popup)$/ + or die "Illegal link: ". $cgi->param('link'); +my $field = my $link = $1; +$field = 'custnum' if $field eq 'popup'; + +my $_date = str2time($cgi->param('_date')); + +my $new = new FS::cust_pay ( { + $field => $linknum, + _date => $_date, + map { + $_, scalar($cgi->param($_)); + } qw(paid payby payinfo paybatch) + #} fields('cust_pay') +} ); + +my $error = $new->insert( 'manual' => 1 ); + +</%init> diff --git a/httemplate/edit/process/cust_pay_pending.html b/httemplate/edit/process/cust_pay_pending.html new file mode 100644 index 000000000..1bad6cffe --- /dev/null +++ b/httemplate/edit/process/cust_pay_pending.html @@ -0,0 +1,68 @@ +<% include('/elements/header-popup.html', $title ) %> +% if ( $error ) { + <FONT SIZE="+1" COLOR="#ff0000">Error: <% $error |h %></FONT> +% } else { + <SCRIPT TYPE="text/javascript"> + window.top.location.reload(); + </SCRIPT> +% } +</BODY> +</HTML> +<%init> + +my $curuser = $FS::CurrentUser::CurrentUser; + +die "access denied" + unless $curuser->access_right('Edit customer pending payments'); + +$cgi->param('action') =~ /^(\w+)$/ or die 'illegal action'; +my $action = $1; + +$cgi->param('paypendingnum') =~ /^(\d+)$/ or die 'illegal paypendingnum'; +my $paypendingnum = $1; +my $cust_pay_pending = + qsearchs({ + 'select' => 'cust_pay_pending.*', + 'table' => 'cust_pay_pending', + 'addl_from' => 'LEFT JOIN cust_main USING ( custnum )', + 'hashref' => { 'paypendingnum' => $paypendingnum }, + 'extra_sql' => ' AND '. $curuser->agentnums_sql, + }) + or die 'unknown paypendingnum'; + +my $error; +my $title; +if ( $action eq 'delete' ) { + + $error = $cust_pay_pending->delete; + if ( $error ) { + $title = 'Error deleting pending payment'; + } else { + $title = 'Pending payment deletion sucessful'; + } + +} elsif ( $action eq 'insert_cust_pay' ) { + + $error = $cust_pay_pending->insert_cust_pay; + if ( $error ) { + $title = 'Error completing pending payment'; + } else { + $title = 'Pending payment completed'; + } + +} elsif ( $action eq 'decline' ) { + + $error = $cust_pay_pending->decline; + if ( $error ) { + $title = 'Error declining pending payment'; + } else { + $title = 'Pending payment completed (decline)'; + } + +} else { + + die "unknown action $action"; + +} + +</%init> diff --git a/httemplate/edit/process/cust_pay_refund.cgi b/httemplate/edit/process/cust_pay_refund.cgi new file mode 100755 index 000000000..2616cad8c --- /dev/null +++ b/httemplate/edit/process/cust_pay_refund.cgi @@ -0,0 +1,13 @@ +<% include('elements/ApplicationCommon.html', + 'error_redirect' => 'cust_pay_refund.cgi', + 'src_table' => 'cust_pay', + 'src_thing' => 'payment', + 'link_table' => 'cust_pay_refund', + ) +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Apply payment'); + +</%init> diff --git a/httemplate/edit/process/cust_pkg.cgi b/httemplate/edit/process/cust_pkg.cgi new file mode 100755 index 000000000..c564c417e --- /dev/null +++ b/httemplate/edit/process/cust_pkg.cgi @@ -0,0 +1,42 @@ +% if ($error) { +% $cgi->param('error', $error); +% $cgi->redirect(popurl(3). 'edit/cust_pkg.cgi?'. $cgi->query_string ); +% } else { +<% $cgi->redirect(popurl(3). "view/cust_main.cgi?$custnum") %> +% } +<%init> + +my $curuser = $FS::CurrentUser::CurrentUser; + +die "access denied" + unless $curuser->access_right('Bulk change customer packages'); + +my $error = ''; + +#untaint custnum +$cgi->param('custnum') =~ /^(\d+)$/; +my $custnum = $1; + +my @remove_pkgnums = map { + /^(\d+)$/ or die "Illegal remove_pkg value!"; + $1; +} $cgi->param('remove_pkg'); + +my( $action, $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; + } + } else { + $error = "Illegal quantity"; + last; + } +} + +$error ||= FS::cust_pkg::order($custnum,\@pkgparts,\@remove_pkgnums); + +</%init> diff --git a/httemplate/edit/process/cust_pkg_detail.html b/httemplate/edit/process/cust_pkg_detail.html new file mode 100644 index 000000000..132ff63c5 --- /dev/null +++ b/httemplate/edit/process/cust_pkg_detail.html @@ -0,0 +1,59 @@ +% if ( $error ) { +<% header('Error') %> +<FONT COLOR="#ff0000"><B><% $error |h %></B></FONT><BR><BR> +<CENTER><INPUT TYPE="BUTTON" VALUE="OK" onClick="parent.cClick()"></CENTER> +</BODY></HTML> +% } else { +<% header($action) %> + <SCRIPT TYPE="text/javascript"> + window.top.location.reload(); + </SCRIPT> + </BODY></HTML> +% } +<%init> + +my %access_right = ( + 'I' => 'Edit customer package invoice details', + 'C' => 'Edit customer package comments', +); + +my %name = ( + 'I' => 'invoice details', + 'C' => 'package comments', +); + +my $curuser = $FS::CurrentUser::CurrentUser; + +$cgi->param('detailtype') =~ /^(\w)$/ or die 'illegal detailtype'; +my $detailtype = $1; + +my $right = $access_right{$detailtype}; +die "access denied" + unless $curuser->access_right($right); + +$cgi->param('pkgnum') =~ /^(\d+)$/ or die 'illegal pkgnum'; +my $pkgnum = $1; + +my $cust_pkg = qsearchs({ + 'table' => 'cust_pkg', + 'addl_from' => 'LEFT JOIN cust_main USING ( custnum )', + 'hashref' => { 'pkgnum' => $pkgnum }, + 'extra_sql' => ' AND '. $curuser->agentnums_sql, +}); + + +my @orig_details = $cust_pkg->cust_pkg_detail($detailtype); + +my $action = ucfirst($name{$detailtype}). + ( scalar(@orig_details) ? ' changed ' : ' added ' ); + +my $param = $cgi->Vars; +my @details = (); +for ( my $row = 0; exists($param->{"detail$row"}); $row++ ) { + push @details, $param->{"detail$row"} + if $param->{"detail$row"} =~ /\S/; +} + +my $error = $cust_pkg->set_cust_pkg_detail($detailtype, @details); + +</%init> diff --git a/httemplate/edit/process/cust_refund.cgi b/httemplate/edit/process/cust_refund.cgi new file mode 100755 index 000000000..5749e5346 --- /dev/null +++ b/httemplate/edit/process/cust_refund.cgi @@ -0,0 +1,56 @@ +%if ( $error ) { +% $cgi->param('error', $error); +<% $cgi->redirect(popurl(2). "cust_refund.cgi?". $cgi->query_string ) %> +%} else { +% +% if ( $link eq 'popup' ) { +% +<% header('Refund entered') %> + <SCRIPT TYPE="text/javascript"> + window.top.location.reload(); + </SCRIPT> + + </BODY></HTML> +% } else { +<% $cgi->redirect(popurl(3). "view/cust_main.cgi?$custnum") %> +% } +%} +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Refund payment') + || $FS::CurrentUser::CurrentUser->access_right('Post refund'); + +$cgi->param('custnum') =~ /^(\d*)$/ or die "Illegal custnum!"; +my $custnum = $1; +my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } ) + or die "unknown custnum $custnum"; + +my $link = $cgi->param('popup') ? 'popup' : ''; + +my $error = ''; +if ( $cgi->param('payby') =~ /^(CARD|CHEK)$/ ) { + my %options = (); + my $bop = $FS::payby::payby2bop{$1}; + $cgi->param('refund') =~ /^(\d*)(\.\d{2})?$/ + or die "illegal refund amount ". $cgi->param('refund'); + my $refund = "$1$2"; + $cgi->param('paynum') =~ /^(\d*)$/ or die "Illegal paynum!"; + my $paynum = $1; + my $reason = $cgi->param('reason'); + my $paydate = $cgi->param('exp_year'). '-'. $cgi->param('exp_month'). '-01'; + $options{'paydate'} = $paydate if $paydate =~ /^\d{2,4}-\d{1,2}-01$/; + $error = $cust_main->realtime_refund_bop( $bop, 'amount' => $refund, + 'paynum' => $paynum, + 'reason' => $reason, + %options ); +} else { + my $new = new FS::cust_refund ( { + map { + $_, scalar($cgi->param($_)); + } fields('cust_refund') #huh? , 'paynum' ) + } ); + $error = $new->insert; +} + +</%init> diff --git a/httemplate/edit/process/cust_svc.cgi b/httemplate/edit/process/cust_svc.cgi new file mode 100644 index 000000000..e22cbb201 --- /dev/null +++ b/httemplate/edit/process/cust_svc.cgi @@ -0,0 +1,30 @@ +%if ( $error ) { +% errorpage($error); +%} else { +% my $svcdb = $new->part_svc->svcdb; +<% $cgi->redirect(popurl(3). "view/$svcdb.cgi?$svcnum") %> +%} +<%init> + +die 'access deined' + unless $FS::CurrentUser::CurrentUser->access_right('Change customer service'); + +my $svcnum = $cgi->param('svcnum'); + +my $old = qsearchs('cust_svc',{'svcnum'=>$svcnum}) if $svcnum; + +my $new = new FS::cust_svc ( { + map { + $_, scalar($cgi->param($_)); + } fields('cust_svc') +} ); + +my $error; +if ( $svcnum ) { + $error=$new->replace($old); +} else { + $error=$new->insert; + $svcnum=$new->getfield('svcnum'); +} + +</%init> diff --git a/httemplate/edit/process/domain_record.cgi b/httemplate/edit/process/domain_record.cgi new file mode 100755 index 000000000..2e427e4fb --- /dev/null +++ b/httemplate/edit/process/domain_record.cgi @@ -0,0 +1,30 @@ +%if ( $error ) { +% errorpage($error); +%} else { +% my $svcnum = $new->svcnum; +<% $cgi->redirect(popurl(3). "view/svc_domain.cgi?$svcnum") %> +%} +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Edit domain nameservice'); + +my $recnum = $cgi->param('recnum'); + +my $old = qsearchs('agent',{'recnum'=>$recnum}) if $recnum; + +my $new = new FS::domain_record ( { + map { + $_, scalar($cgi->param($_)); + } fields('domain_record') +} ); + +my $error; +if ( $recnum ) { + $error=$new->replace($old); +} else { + $error=$new->insert; + $recnum=$new->getfield('recnum'); +} + +</%init> diff --git a/httemplate/edit/process/elements/ApplicationCommon.html b/httemplate/edit/process/elements/ApplicationCommon.html new file mode 100644 index 000000000..2782dc231 --- /dev/null +++ b/httemplate/edit/process/elements/ApplicationCommon.html @@ -0,0 +1,77 @@ +<%doc> + +Examples: + + #cust_bill_pay + include('elements/ApplicationCommon.html', + 'error_redirect' => 'cust_bill_pay.cgi', + 'src_table' => 'cust_pay', + 'src_thing' => 'payment', + 'link_table' => 'cust_bill_pay', + ) + + #cust_credit_bill + include('elements/ApplicationCommon.html', + 'error_redirect' => 'cust_credit_bill.cgi', + 'src_table' => 'cust_credit', + 'src_thing' => 'credit', + 'link_table' => 'cust_credit_bill', + ) + +</%doc> +%if ( $error ) { +% $cgi->param('error', $error); +<% $cgi->redirect(popurl(2). $opt{error_redirect}. '?'. $cgi->query_string ) %> +%} else { +<% header("$src_thing application$to sucessful") %> + <SCRIPT TYPE="text/javascript"> + window.top.location.reload(); + </SCRIPT> + </BODY> + </HTML> +% } +<%init> + +my %opt = @_; + +my $src_thing = ucfirst($opt{'src_thing'}); +my $src_table = $opt{'src_table'}; +my $src_pkey = dbdef->table($src_table)->primary_key; + +my $to = $opt{'link_table'} =~ /refund/ ? ' to Refund' : ''; + +$cgi->param($src_pkey) =~ /^(\d+)$/ or die "Illegal $src_pkey!"; +my $src_pkeyvalue = $1; + +my $src = qsearchs($src_table, { $src_pkey => $src_pkeyvalue } ) + or die "No such $src_pkey: $src_pkeyvalue"; + +my $cust_main = qsearchs('cust_main', { 'custnum' => $src->custnum } ) + or die "Bogus $src_thing: not attached to customer"; + +my $custnum = $cust_main->custnum; + +my $new; +# $new = new FS::cust_refund ( { +# 'reason' => 'Refunding payment', #enter reason in UI +# 'refund' => $cgi->param('amount'), +# 'payby' => 'BILL', +# #'_date' => $cgi->param('_date'), +# 'payinfo' => 'Cash', #enter payinfo in UI +# 'paynum' => $paynum, +# } ); +#} else { + + my $class = 'FS::'. $opt{link_table}; + + $new = $class->new( { + map { + $_ => scalar($cgi->param($_)); + } fields($opt{link_table}) + } ); + +#} + +my $error = $new->insert; + +</%init> diff --git a/httemplate/edit/process/elements/process.html b/httemplate/edit/process/elements/process.html new file mode 100644 index 000000000..5befdd337 --- /dev/null +++ b/httemplate/edit/process/elements/process.html @@ -0,0 +1,268 @@ +<%doc> + +Example: + + include( 'elements/process.html', + + ### + # required + ### + + 'table' => 'tablename', + + #? 'primary_key' => #required when the dbdef doesn't know...??? + #? 'fields' => [] #"" + + ### + # optional + ### + + 'viewall_dir' => '', #'search' or 'browse', defaults to 'search' + 'viewall_ext' => 'html', #'cgi' or 'html', defaults to 'html' + OR + 'redirect' => 'view/table.cgi?', # value of primary key is appended + # (string or coderef returning a string) + OR + 'popup_reload' => 'Momentary success message', #will reload parent window + + 'error_redirect' => popurl(2).'edit/table.cgi?', #query string appended + + 'edit_ext' => 'html', #defaults to 'html', you might want 'cgi' while the + #naming is still inconsistent + + 'copy_on_empty' => [ 'old_field_name', 'another_old_field', ... ], + + 'clear_on_error' => [ 'form_field1', 'form_field2', ... ], + + #pass an arrayref of hashrefs for multiple m2ms or m2names + #be certain you incorporate m2m_Common if you see error: param + + 'process_m2m' => { 'link_table' => 'link_table_name', + 'target_table' => 'target_table_name', + #optional (see m2m_Common::process_m2m), if not specified + # all CGI params will be passed) + 'params' => + }, + 'process_m2name' => { 'link_table' => 'link_table_name', + 'link_static' => { 'column' => 'value' }, + 'num_col' => 'column', #if column name is different in + #link_table than source_table + 'name_col' => 'name_column', + 'names_list' => [ 'list', 'names' ], + + 'param_style' => 'link_table.value checkboxes', + #or# + 'param_style' => 'name_colN values', + + + }, + + #checks CGI params and whatever else before much else runs + #return an error string or empty for no error + 'precheck_callback' => sub { my( $cgi ) = @_; }, + + #supplies arguments to insert() and replace() + # for use with tables that are FS::option_Common + 'args_callback' => sub { my( $cgi, $object ) = @_; }, + + 'debug' => 1, #turns on debugging output + + #agent virtualization + 'agent_virt' => 1, + 'agent_null_right' => 'Access Right Name', + + ) + +</%doc> +%if ( $error ) { +% +% my $edit_ext = $opt{'edit_ext'} || 'html'; +% my $url = $opt{'error_redirect'} || popurl(2)."$table.$edit_ext"; +% if ( length($cgi->query_string) > 1920 ) { #stupid IE 2083 URL limit +% +% my $session = int(rand(4294967296)); #XXX +% my $pref = new FS::access_user_pref({ +% 'usernum' => $FS::CurrentUser::CurrentUser->usernum, +% 'prefname' => "redirect$session", +% 'prefvalue' => $cgi->query_string, +% 'expiration' => time + 3600, #1h? 1m? +% }); +% my $pref_error = $pref->insert; +% if ( $pref_error ) { +% die "FATAL: couldn't even set redirect cookie: $pref_error". +% " attempting to set redirect$session to ". $cgi->query_string."\n"; +% } +% +<% $cgi->redirect("$url?redirect=$session") %> +% +% } else { +% +<% $cgi->redirect("$url?". $cgi->query_string ) %> +% +% } +% +% #different ways of handling success +% +%} elsif ( $opt{'popup_reload'} ) { + + <% include('/elements/header-popup.html', $opt{'popup_reload'} ) %> + + <SCRIPT TYPE="text/javascript"> + window.top.location.reload(); + </SCRIPT> + + </BODY> + </HTML> + +%} else { +% +% $opt{'redirect'} = &{$opt{'redirect'}}($cgi, $new) +% if ref($opt{'redirect'}) eq 'CODE'; +% +% if ( $opt{'redirect'} ) { +% +<% $cgi->redirect( $opt{'redirect'}. $pkeyvalue ) %> +% +% } else { +% +% my $ext = $opt{'viewall_ext'} || 'html'; +% +<% $cgi->redirect( popurl(3). ($opt{viewall_dir}||'search'). "/$table.$ext" ) %> +% +% } +% +%} +% +<%init> + +my $me = 'process.html:'; + +my(%opt) = @_; + +my $curuser = $FS::CurrentUser::CurrentUser; + +my $error = ''; +if ( $opt{'precheck_callback'} ) { + $error = &{ $opt{'precheck_callback'} }( $cgi ); +} + +#false laziness w/edit.html +my $table = $opt{'table'}; +my $class = "FS::$table"; +my $pkey = dbdef->table($table)->primary_key; #? $opt{'primary_key'} || +my $fields = $opt{'fields'} + #|| [ grep { $_ ne $pkey } dbdef->table($table)->columns ]; + || [ fields($table) ]; + +my $pkeyvalue = $cgi->param($pkey); + +my $old = ''; +if ( $pkeyvalue ) { + $old = qsearchs({ + 'table' => $table, + 'hashref' => { $pkey => $pkeyvalue }, + 'extra_sql' => ( $opt{'agent_virt'} + ? ' AND '. $curuser->agentnums_sql( + 'null_right' => $opt{'agent_null_right'} + ) + : '' + ), + }); +} + +my %hash = + map { my @entry = ( $_ => scalar($cgi->param($_)) ); + $opt{'value_callback'} ? ( $_ => &{ $opt{'value_callback'} }( @entry )) + : ( @entry ) + } @$fields; + +my $new = $class->new( \%hash ); + +if ($old && exists($opt{'copy_on_empty'})) { + foreach my $field (@{$opt{'copy_on_empty'}}) { + $new->set($field, $old->get($field)) + unless scalar($cgi->param($field)); + } +} + +if ( $opt{'agent_virt'} ) { + die "illegal agentnum" + unless $curuser->agentnums_href->{$new->agentnum} + or $opt{'agent_null_right'} + && ! $new->agentnum + && $curuser->access_right($opt{'agent_null_right'}); +} + +$error ||= $new->check; + +my @args = (); +if ( !$error && $opt{'args_callback'} ) { + @args = &{ $opt{'args_callback'} }( $cgi, $new ); +} + +if ( !$error && $opt{'debug'} ) { + warn "$me updating record in $table table using $class class\n"; + warn Dumper(\%hash); + warn "with args: \n". Dumper(\@args) if @args; +} + +if ( !$error ) { + if ( $pkeyvalue ) { + $error = $new->replace($old, @args); + } else { + $error = $new->insert(@args); + $pkeyvalue = $new->getfield($pkey); + } +} + +if ( !$error && $opt{'process_m2m'} ) { + + my @process_m2m = ref($opt{'process_m2m'}) eq 'ARRAY' + ? @{ $opt{'process_m2m'} } + : ( $opt{'process_m2m'} ); + + foreach my $process_m2m (@process_m2m) { + + $process_m2m->{'params'} ||= scalar($cgi->Vars); + + warn "$me processing m2m:\n". Dumper( %$process_m2m ) + if $opt{'debug'}; + + $error = $new->process_m2m( %$process_m2m ); + } + +} + +if ( !$error && $opt{'process_m2name'} ) { + + my @process_m2name = ref($opt{'process_m2name'}) eq 'ARRAY' + ? @{ $opt{'process_m2name'} } + : ( $opt{'process_m2name'} ); + + + foreach my $process_m2name (@process_m2name) { + + if ( $opt{'debug'} ) { + warn "$me processing m2name:\n". Dumper( %{ $process_m2name }, + 'params' => scalar($cgi->Vars), + ); + } + + $error = $new->process_m2name( %{ $process_m2name }, + 'params' => scalar($cgi->Vars), + ); + } + +} + + +if ( $error ) { + $cgi->param('error', $error); + if ( $opt{'clear_on_error'} && scalar(@{$opt{'clear_on_error'}}) ) { + foreach my $field (@{$opt{'clear_on_error'}}) { + $cgi->param($field, '') + } + } +} + +</%init> diff --git a/httemplate/edit/process/elements/svc_Common.html b/httemplate/edit/process/elements/svc_Common.html new file mode 100644 index 000000000..8e8c99a42 --- /dev/null +++ b/httemplate/edit/process/elements/svc_Common.html @@ -0,0 +1,15 @@ +% +% +% my %opt = @_; +% my $table = $opt{'table'}; +% $opt{'fields'} ||= [ fields($table) ]; +% push @{ $opt{'fields'} }, qw( pkgnum svcpart ); +% +% +<% include( 'process.html', + 'edit_ext' => 'cgi', + 'redirect' => popurl(3)."view/$table.cgi?", + %opt, + ) +%> + diff --git a/httemplate/edit/process/generic.cgi b/httemplate/edit/process/generic.cgi new file mode 100644 index 000000000..642876386 --- /dev/null +++ b/httemplate/edit/process/generic.cgi @@ -0,0 +1,77 @@ +%if($error) { +% $cgi->param('error', $error); +<% $cgi->redirect($redirect_error . '?' . $cgi->query_string) %> +%} else { +<% $cgi->redirect($redirect_ok) %> +%} +<%doc> + +See elements/process.html, newer and somewhat along the same lines, +though it still makes you setup a process file for the table. +Perhaps safer, perhaps more of a pain in the ass. + +In any case, this is probably pretty deprecated; it is only used by +part_virtual_field.cgi, and so its ACL is hardcoded to 'Configuration'. + +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). + +</%doc> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +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()); + +</%init> diff --git a/httemplate/edit/process/inventory_class.html b/httemplate/edit/process/inventory_class.html new file mode 100644 index 000000000..dbf978e72 --- /dev/null +++ b/httemplate/edit/process/inventory_class.html @@ -0,0 +1,11 @@ +<% include( 'elements/process.html', + 'table' => 'inventory_class', + 'viewall_dir' => 'browse', + ) +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +</%init> diff --git a/httemplate/edit/process/invoice_logo.html b/httemplate/edit/process/invoice_logo.html new file mode 100644 index 000000000..524d32542 --- /dev/null +++ b/httemplate/edit/process/invoice_logo.html @@ -0,0 +1,25 @@ +<%init> + +my $curuser = $FS::CurrentUser::CurrentUser; + +die "access denied" + unless $curuser->access_right('Configuration'); + +my $conf = new FS::Conf; + +$cgi->param('type') =~ /^(png|eps)$/ or die "illegal type"; +my $type = $1; + +$cgi->param('name') =~ /^([^\.\/]*)$/ or die "illegal name"; +my $tname = my $name = $1; +$tname = "_$tname" if length($tname); + +$cgi->param('preview_session') =~ /^(\w*)$/ or die "illegal preview_session"; +my $session = $1; +my $data = decode_base64( $curuser->option("logo_preview$session") ); + +$conf->set_binary("logo$name.$type", $data); + +$cgi->redirect(popurl(3). "edit/invoice_logo.html?type=$type;name=$name;msg=Logo%20changed"); + +</%init> diff --git a/httemplate/edit/process/invoice_template.html b/httemplate/edit/process/invoice_template.html new file mode 100644 index 000000000..6c9371ad1 --- /dev/null +++ b/httemplate/edit/process/invoice_template.html @@ -0,0 +1,15 @@ +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $conf = new FS::Conf; + +my $confname = $cgi->param('confname'); +my $value = $cgi->param('value'); + +$conf->set($confname, $value); + +$cgi->redirect(popurl(3). 'browse/invoice_template.html'); + +</%init> diff --git a/httemplate/edit/process/msgcat.cgi b/httemplate/edit/process/msgcat.cgi new file mode 100644 index 000000000..7175fa2b3 --- /dev/null +++ b/httemplate/edit/process/msgcat.cgi @@ -0,0 +1,22 @@ +%if ( $error ) { +% $cgi->param('error',$error); +<% $cgi->redirect($p. "msgcat.cgi?". $cgi->query_string ) %> +%} else { +<% $cgi->redirect(popurl(3). "browse/msgcat.cgi") %> +%} +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $error; +foreach my $param ( grep { /^\d+$/ } $cgi->param ) { + my $old = qsearchs('msgcat', { msgnum=>$param } ); + next if $old->msg eq $cgi->param($param); #no need to update identical records + my $new = new FS::msgcat { $old->hash }; + $new->msg($cgi->param($param)); + $error = $new->replace($old); + last if $error; +} + +</%init> diff --git a/httemplate/edit/process/part_bill_event.cgi b/httemplate/edit/process/part_bill_event.cgi new file mode 100755 index 000000000..eb0529bb8 --- /dev/null +++ b/httemplate/edit/process/part_bill_event.cgi @@ -0,0 +1,106 @@ +%if ( $error ) { +% $cgi->param('error', $error); +<% $cgi->redirect(popurl(2). "part_bill_event.cgi?". $cgi->query_string ) %> +%} else { +<% $cgi->redirect(popurl(3)."browse/part_bill_event.cgi") %> +%} +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $eventpart = $cgi->param('eventpart'); + +my $old = qsearchs('part_bill_event',{'eventpart'=>$eventpart}) if $eventpart; + +#s/days/seconds/ +$cgi->param('seconds', int( $cgi->param('days') * 86400 ) ); + +my $error; +if ( ! $cgi->param('plan_weight_eventcode') ) { + $error = "Must select an action"; +} else { + + $cgi->param('plan_weight_eventcode') =~ /^([\w\-]+):(\d+):(.*)$/s + or die "illegal plan_weight_eventcode:". + $cgi->param('plan_weight_eventcode'); + $cgi->param('plan', $1); + $cgi->param('weight', $2); + my $eventcode = $3; + my $plandata = ''; + + my $rnum; + my $rtype; + my $reasonm; + my $class = ''; + $class='c' if ($eventcode =~ /cancel/); + $class='s' if ($eventcode =~ /suspend/); + if ($class) { + $cgi->param("${class}reason") =~ /^(-?\d+)$/ + or $error = "Invalid ${class}reason"; + $rnum = $1; + if ($rnum == -1) { + $cgi->param("new${class}reasonT") =~ /^(\d+)$/ + or $error = "Invalid new${class}reasonT"; + $rtype = $1; + $cgi->param("new${class}reason") =~ /^([\s\w]+)$/ + or $error = "Invalid new${class}reason"; + $reasonm = $1; + } + } + + if ($rnum == -1 && !$error) { + my $reason = new FS::reason ({ 'reason' => $reasonm, + 'reason_type' => $rtype, + }); + $error = $reason->insert; + unless ($error) { + $rnum = $reason->reasonnum; + $cgi->param("${class}reason", $rnum); + $cgi->param("new${class}reason", ''); + $cgi->param("new${class}reasonT", ''); + } + } + + while ( $eventcode =~ /%%%(\w+)%%%/ ) { + my $field = $1; + my $value = join(', ', $cgi->param($field) ); + $cgi->param($field, $value); #in case it errors out + $eventcode =~ s/%%%$field%%%/$value/; + $plandata .= "$field $value\n"; + } + $cgi->param('eventcode', $eventcode); + $cgi->param('plandata', $plandata); + + unless($error) { + + if ( $eventpart ) { + + my $new = new FS::part_bill_event ( { + map { $_ => scalar($cgi->param($_)) } + fields('part_bill_event'), + } ); + $new->setfield('reason' => $rnum); + $error = $new->replace($old); + + } else { + + foreach my $payby ( $cgi->param('payby') ) { + my $new = new FS::part_bill_event ( { + map { $_ => scalar($cgi->param($_)) } + grep { $_ ne 'payby' } + fields('part_bill_event') + } ); + $new->setfield('payby' => $payby); + $new->setfield('reason' => $rnum ); + $error = $new->insert; + last if $error; + } + + } + + } + +} + +</%init> diff --git a/httemplate/edit/process/part_event.html b/httemplate/edit/process/part_event.html new file mode 100644 index 000000000..428025fd1 --- /dev/null +++ b/httemplate/edit/process/part_event.html @@ -0,0 +1,86 @@ +<% include( 'elements/process.html', + #'debug' => 1, + 'table' => 'part_event', + 'viewall_dir' => 'browse', + 'process_m2name' => + { + 'link_table' => 'part_event_condition', + 'num_col' => 'eventpart', + 'name_col' => 'conditionname', + 'names_list' => [ FS::part_event_condition->all_conditionnames() ], + 'param_style' => 'name_colN values', + 'args_callback' => sub { # FS/FS/m2name_Common.pm + my( $object, $prefix, $params, $listref ) = @_; + #warn "$object $prefix $params $listref\n"; + + my $cond = $object->conditionname; + + my %option_fields = $object->option_fields; + + push @$listref, map { + my $field = $_; + + my $cgi_field = "$prefix$cond.$field"; + + my $value = $params->{$cgi_field}; + + my $info = $option_fields{$_}; + $info = { label=>$info, type=>'text' } + unless ref($info); + + if ( $info->{'type'} =~ + /^(select|checkbox)-?multiple$/ + or $info->{'type'} =~ /^select/ + && $info->{'multiple'} + ) + { + #special processing for compound fields + $value = { map { $_ => 1 } + split(/\0/, $value) + }; + } elsif ( $info->{'type'} eq 'freq' ) { + $value .= $params->{$cgi_field.'_units'}; + } + + #warn "value of $cgi_field is $value\n"; + + ( $field => $value ); + } + keys %option_fields; + }, + }, + + 'args_callback' => sub { + + my( $cgi, $object ) = @_; + + my $prefix = $object->action.'.'; + + map { my $option = $_; + #my $value = scalar( $cgi->param( "$prefix$option" ) ); + my $value = join(',', $cgi->param( "$prefix$option" ) ); + + if ( $option eq 'reasonnum' && $value == -1 ) { + $value = { + 'typenum' => scalar( $cgi->param( "new$prefix${option}T" ) ), + 'reason' => scalar( $cgi->param( "new$prefix${option}" ) ), + }; + } + + ( $option => $value ); + } + @{ $object->option_fields_listref }; + + }, + + 'agent_virt' => 1, + 'agent_null_right' => 'Edit global billing events', +) +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Edit billing events') + || $FS::CurrentUser::CurrentUser->access_right('Edit global billing events'); + +</%init> diff --git a/httemplate/edit/process/part_export.cgi b/httemplate/edit/process/part_export.cgi new file mode 100644 index 000000000..b5f82e892 --- /dev/null +++ b/httemplate/edit/process/part_export.cgi @@ -0,0 +1,41 @@ +%if ( $error ) { +% $cgi->param('error', $error ); +<% $cgi->redirect(popurl(2). "part_export.cgi?". $cgi->query_string ) %> +%} else { +<% $cgi->redirect(popurl(3). "browse/part_export.cgi") %> +%} +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $exportnum = $cgi->param('exportnum'); + +my $old = qsearchs('part_export', { 'exportnum'=>$exportnum } ) if $exportnum; + +#fixup options +#warn join('-', split(',',$cgi->param('options'))); +my %options = map { + my $value = $cgi->param($_); + $value =~ s/\r\n/\n/g; #browsers? (textarea) + $_ => $value; +} split(',', $cgi->param('options')); + +my $new = new FS::part_export ( { + map { + $_, scalar($cgi->param($_)); + } fields('part_export') +} ); + +my $error; +if ( $exportnum ) { + #warn $old; + #warn $exportnum; + #warn $new->machine; + $error = $new->replace($old,\%options); +} else { + $error = $new->insert(\%options); +# $exportnum = $new->exportnum; +} + +</%init> diff --git a/httemplate/edit/process/part_pkg.cgi b/httemplate/edit/process/part_pkg.cgi new file mode 100755 index 000000000..96c5b36b7 --- /dev/null +++ b/httemplate/edit/process/part_pkg.cgi @@ -0,0 +1,198 @@ +<% include( 'elements/process.html', + #'debug' => 1, + 'table' => 'part_pkg', + 'agent_virt' => 1, + 'agent_null_right' => \@agent_null_right, + 'redirect' => $redirect_callback, + 'viewall_dir' => 'browse', + 'viewall_ext' => 'cgi', + 'edit_ext' => 'cgi', + 'precheck_callback' => $precheck_callback, + 'args_callback' => $args_callback, + 'process_m2m' => \@process_m2m, + ) +%> +<%init> + +my $customizing = ( ! $cgi->param('pkgpart') && $cgi->param('pkgnum') ); + +my $curuser = $FS::CurrentUser::CurrentUser; + +my $edit_global = 'Edit global package definitions'; +my $customize = 'Customize customer package'; + +die "access denied" + unless $curuser->access_right('Edit package definitions') + || $curuser->access_right($edit_global) + || ( $customizing && $curuser->access_right($customize) ); + +my @agent_null_right = ( $edit_global ); +push @agent_null_right, $customize if $customizing; + + +my $precheck_callback = sub { + my( $cgi ) = @_; + + my $conf = new FS::Conf; + + foreach (qw( setuptax recurtax disabled )) { + $cgi->param($_, '') unless defined $cgi->param($_); + } + + return 'Must select a tax class' + if $cgi->param('taxclass') eq '(select)'; + + my @agents = (); + foreach ($cgi->param('agent_type')) { + /^(\d+)$/; + push @agents, $1 if $1; + } + return "At least one agent type must be specified." + unless scalar(@agents) + || ( $cgi->param('clone') && $cgi->param('clone') =~ /^\d+$/ ) + || ( !$cgi->param('pkgpart') && $conf->exists('agent-defaultpkg') ) + || $cgi->param('disabled') + || $cgi->param('agentnum'); + + return ''; + +}; + +my $custnum = ''; + +my $args_callback = sub { + my( $cgi, $new ) = @_; + + my @args = ( 'primary_svc' => scalar($cgi->param('pkg_svc_primary')) ); + + ## + #options + ## + + $cgi->param('plan') =~ /^(\w+)$/ or die 'unparsable plan'; + my $plan = $1; + + tie my %plans, 'Tie::IxHash', %{ FS::part_pkg::plan_info() }; + my $href = $plans{$plan}->{'fields'}; + + my $error = ''; + my $options = $cgi->param($plan."__OPTIONS"); + my @options = split(',', $options); + my %options = + map { my $optionname = $_; + my $param = $plan."__$optionname"; + my $parser = exists($href->{$optionname}{parse}) + ? $href->{$optionname}{parse} + : sub { shift }; + my $value = join(', ', &$parser($cgi->param($param))); + my $check = $href->{$optionname}{check}; + if ( $check && ! &$check($value) ) { + $value = join(', ', $cgi->param($param)); + $error ||= "Illegal ". + ($href->{$optionname}{name}||$optionname). ": $value"; + } + ( $optionname => $value ); + } + @options; + + foreach ( split(',', $cgi->param('taxproductnums') ) ) { + my $value = $cgi->param("taxproductnum_$_"); + $error ||= "Illegal taxproductnum_$_: $value" + unless ( $value =~ /^\d*$/ ); + $options{"usage_taxproductnum_$_"} = $value; + } + + $options{$_} = scalar( $cgi->param($_) ) + for (qw( setup_fee recur_fee )); + + push @args, 'options' => \%options; + + ### + #pkg_svc + ### + + my %pkg_svc = map { $_ => scalar($cgi->param("pkg_svc$_")) } + map { $_->svcpart } + qsearch('part_svc', {} ); + + push @args, 'pkg_svc' => \%pkg_svc; + + ### + # cust_pkg and custnum_ref (inserts only) + ### + unless ( $cgi->param('pkgpart') ) { + push @args, 'cust_pkg' => scalar($cgi->param('pkgnum')), + 'custnum_ref' => \$custnum; + } + + warn "args: ".join('/', @args). "\n"; + + @args; + +}; + +my $redirect_callback = sub { + #my( $cgi, $new ) = @_; + return '' unless $custnum; + popurl(3). "view/cust_main.cgi?keywords=$custnum;dummy="; +}; + +#these should probably move to @args above and be processed by part_pkg.pm... + +$cgi->param('tax_override') =~ /^([\d,]+)$/; +my (@tax_overrides) = (grep "$_", split (",", $1)); + +my @process_m2m = ( + { + 'link_table' => 'part_pkg_taxoverride', + 'target_table' => 'tax_class', + 'params' => \@tax_overrides, + }, + { 'link_table' => 'part_pkg_link', + 'target_table' => 'part_pkg', + 'base_field' => 'src_pkgpart', + 'target_field' => 'dst_pkgpart', + 'hashref' => { 'link_type' => 'bill' }, + 'params' => [ map $cgi->param($_), grep /^bill_dst_pkgpart/, $cgi->param ], + }, + { 'link_table' => 'part_pkg_link', + 'target_table' => 'part_pkg', + 'base_field' => 'src_pkgpart', + 'target_field' => 'dst_pkgpart', + 'hashref' => { 'link_type' => 'svc' }, + 'params' => [ map $cgi->param($_), grep /^svc_dst_pkgpart/, $cgi->param ], + }, +); + +foreach my $override_class ($cgi->param) { + next unless $override_class =~ /^tax_override_(\w+)$/; + my $class = $1; + + my (@tax_overrides) = (grep "$_", split (",", $1)) + if $cgi->param($override_class) =~ /^([\d,]+)$/; + + push @process_m2m, { + 'link_table' => 'part_pkg_taxoverride', + 'target_table' => 'tax_class', + 'hashref' => { 'usage_class' => $class }, + 'params' => [ @tax_overrides ], + }; + +} + +my $conf = new FS::Conf; + +if ( $cgi->param('pkgpart') || ! $conf->exists('agent_defaultpkg') ) { + my @agents = (); + foreach ($cgi->param('agent_type')) { + /^(\d+)$/; + push @agents, $1 if $1; + } + push @process_m2m, { + 'link_table' => 'type_pkgs', + 'target_table' => 'agent_type', + 'params' => \@agents, + }; +} + +</%init> diff --git a/httemplate/edit/process/part_pkg_taxclass.html b/httemplate/edit/process/part_pkg_taxclass.html new file mode 100644 index 000000000..8f149bb94 --- /dev/null +++ b/httemplate/edit/process/part_pkg_taxclass.html @@ -0,0 +1,53 @@ +% if ( $error ) { +% $cgi->param('error', $error); +<% $cgi->redirect(popurl(2). "part_pkg_taxclass.html?". $cgi->query_string ) %> +%} else { +<% $cgi->redirect(popurl(3). "browse/cust_main_county.cgi?taxclass=". uri_escape($part_pkg_taxclass->taxclass) ) %> +%} +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $part_pkg_taxclass = new FS::part_pkg_taxclass { + 'taxclass' => $cgi->param('taxclass'), +}; + +#maybe this whole thing should be in a transaction. at some point, no biggie +#none of the follow-up stuff will fail unless there's a more serious problem +#than a hanging record in part_pkg_taxclass... + +my $error = $part_pkg_taxclass->insert; + +unless ( $error ) { + #auto-add the new taxclass to any regions that have taxclasses already + + my $sth = dbh->prepare(" + SELECT country, state, county FROM cust_main_county + WHERE taxclass IS NOT NULL AND taxclass != '' + GROUP BY country, state, county + ") or die dbh->errstr; + $sth->execute or die $sth->errstr; + + while ( my $row = $sth->fetchrow_hashref ) { + warn "inserting for $row"; + my $cust_main_county = new FS::cust_main_county { + 'country' => $row->{country}, + 'state' => $row->{state}, + 'county' => $row->{county}, + 'tax' => 0, + 'taxclass' => $part_pkg_taxclass->taxclass, + #exempt_amount + #taxname + #setuptax + #recurtax + }; + $error = $cust_main_county->insert; + #last if $error; + die $error if $error; + } + + +} + +</%init> diff --git a/httemplate/edit/process/part_referral.html b/httemplate/edit/process/part_referral.html new file mode 100755 index 000000000..40cbc97bf --- /dev/null +++ b/httemplate/edit/process/part_referral.html @@ -0,0 +1,12 @@ +<% include( 'elements/process.html', + 'table' => 'part_referral', + 'viewall_dir' => 'browse', + ) +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Edit advertising sources') + || $FS::CurrentUser::CurrentUser->access_right('Edit global advertising sources'); + +</%init> diff --git a/httemplate/edit/process/part_svc.cgi b/httemplate/edit/process/part_svc.cgi new file mode 100755 index 000000000..65de3fc6c --- /dev/null +++ b/httemplate/edit/process/part_svc.cgi @@ -0,0 +1,9 @@ +<% $server->process %> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $server = new FS::UI::Web::JSRPC 'FS::part_svc::process', $cgi; + +</%init> diff --git a/httemplate/edit/process/payment_gateway.html b/httemplate/edit/process/payment_gateway.html new file mode 100644 index 000000000..b16bc3d27 --- /dev/null +++ b/httemplate/edit/process/payment_gateway.html @@ -0,0 +1,35 @@ +%if ( $error ) { +% $cgi->param('error', $error); +<% $cgi->redirect(popurl(2). "payment_gateway.html?". $cgi->query_string ) %> +%} else { +<% $cgi->redirect(popurl(3). "browse/payment_gateway.html") %> +%} +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $gatewaynum = $cgi->param('gatewaynum'); + +my $old = qsearchs('payment_gateway',{'gatewaynum'=>$gatewaynum}) if $gatewaynum; + +my $new = new FS::payment_gateway ( { + map { + $_, scalar($cgi->param($_)); + } fields('payment_gateway') +} ); + +my @options = split(/\r?\n/, $cgi->param('gateway_options') ); +pop @options + if scalar(@options) % 2 && $options[-1] =~ /^\s*$/; +my %options = @options; + +my $error; +if ( $gatewaynum ) { + $error=$new->replace($old, \%options); +} else { + $error=$new->insert(\%options); + $gatewaynum=$new->getfield('gatewaynum'); +} + +</%init> diff --git a/httemplate/edit/process/pkg_category.html b/httemplate/edit/process/pkg_category.html new file mode 100644 index 000000000..50cd5cb29 --- /dev/null +++ b/httemplate/edit/process/pkg_category.html @@ -0,0 +1,11 @@ +<% include( 'elements/process.html', + 'table' => 'pkg_category', + 'viewall_dir' => 'browse', + ) +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +</%init> diff --git a/httemplate/edit/process/pkg_class.html b/httemplate/edit/process/pkg_class.html new file mode 100644 index 000000000..b196df3f7 --- /dev/null +++ b/httemplate/edit/process/pkg_class.html @@ -0,0 +1,11 @@ +<% include( 'elements/process.html', + 'table' => 'pkg_class', + 'viewall_dir' => 'browse', + ) +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +</%init> diff --git a/httemplate/edit/process/prepay_credit.cgi b/httemplate/edit/process/prepay_credit.cgi new file mode 100644 index 000000000..8f2eb2b25 --- /dev/null +++ b/httemplate/edit/process/prepay_credit.cgi @@ -0,0 +1,62 @@ +%unless ( ref($error) ) { +% $cgi->param('error', $error ); +<% $cgi->redirect(popurl(3). "edit/prepay_credit.cgi?". $cgi->query_string ) %> +% } else { + +<% include('/elements/header.html', "$num prepaid cards generated". + ( $agent ? ' for '.$agent->agent : '' ) + ) +%> + +<FONT SIZE="+1"> +% foreach my $card ( @$error ) { + + <code><% $card %></code> + - + <% $hashref->{amount} ? sprintf('$%.2f', $hashref->{amount} ) : '' %> + <% $hashref->{amount} && $hashref->{seconds} ? 'and' : '' %> + <% $hashref->{seconds} ? duration_exact($hashref->{seconds}) : '' %> + <% $hashref->{upbytes} ? FS::UI::bytecount::bytecount_unexact($hashref->{upbytes}) : '' %> + <% $hashref->{downbytes} ? FS::UI::bytecount::bytecount_unexact($hashref->{downbytes}) : '' %> + <% $hashref->{totalbytes} ? FS::UI::bytecount::bytecount_unexact($hashref->{totalbytes}) : '' %> + <br> +% } + +</FONT> + +<% include('/elements/footer.html') %> + +% } +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $hashref = {}; + +my $agent = ''; +if ( $cgi->param('agentnum') =~ /^(\d+)$/ ) { + $agent = qsearchs('agent', { 'agentnum' => $hashref->{agentnum}=$1 } ); +} + +my $error = ''; + +my $num = 0; +if ( $cgi->param('num') =~ /^\s*(\d+)\s*$/ ) { + $num = $1; +} else { + $error = 'Illegal number of prepaid cards: '. $cgi->param('num'); +} + +$hashref->{amount} = $cgi->param('amount'); +$hashref->{seconds} = $cgi->param('seconds') * $cgi->param('multiplier'); +$hashref->{upbytes} = $cgi->param('upbytes') * $cgi->param('upmultiplier'); +$hashref->{downbytes} = $cgi->param('downbytes') * $cgi->param('downmultiplier'); +$hashref->{totalbytes} = $cgi->param('totalbytes') * $cgi->param('totalmultiplier'); + +$error ||= FS::prepay_credit::generate( $num, + scalar($cgi->param('type')), + $hashref + ); + +</%init> diff --git a/httemplate/edit/process/quick-charge.cgi b/httemplate/edit/process/quick-charge.cgi new file mode 100644 index 000000000..8fa57ddea --- /dev/null +++ b/httemplate/edit/process/quick-charge.cgi @@ -0,0 +1,68 @@ +% if ( $error ) { +% $cgi->param('error', $error ); +<% $cgi->redirect($p.'quick-charge.html?'. $cgi->query_string) %> +% } else { +<% header("One-time charge added") %> + <SCRIPT TYPE="text/javascript"> + window.top.location.reload(); + </SCRIPT> + </BODY></HTML> +% } +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('One-time charge'); + +my $error = ''; +my $conf = new FS::conf; +my $param = $cgi->Vars; + +my @description = (); +for ( my $row = 0; exists($param->{"description$row"}); $row++ ) { + push @description, $param->{"description$row"} + if ($param->{"description$row"} =~ /\S/); +} + +$param->{"custnum"} =~ /^(\d+)$/ + or $error .= "Illegal customer number " . $param->{"custnum"} . " "; +my $custnum = $1; + +$param->{"amount"} =~ /^\s*(\d+(\.\d{1,2})?)\s*$/ + or $error .= "Illegal amount " . $param->{"amount"} . " "; +my $amount = $1; + +my $quantity = 1; +if ( $cgi->param('quantity') =~ /^\s*(\d+)\s*$/ ) { + $quantity = $1; +} + +$param->{'tax_override'} =~ /^\s*([,\d]*)\s*$/ + or $error .= "Illegal tax override " . $param->{"tax_override"} . " "; +my $override = $1; + +if ( $param->{'taxclass'} eq '(select)' ) { + $error .= "Must select a tax class. " + unless ($conf->exists('enable_taxproducts') && + ( $override || $param->{taxproductnum} ) + ); + $cgi->param('taxclass', ''); +} + +unless ( $error ) { + my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } ) + or $error .= "Unknown customer number $custnum. "; + + $error ||= $cust_main->charge( { + 'amount' => $amount, + 'quantity' => $quantity, + 'pkg' => scalar($cgi->param('pkg')), + 'setuptax' => scalar($cgi->param('setuptax')), + 'taxclass' => scalar($cgi->param('taxclass')), + 'taxproductnum' => scalar($cgi->param('taxproductnum')), + 'tax_override' => $override, + 'classnum' => scalar($cgi->param('classnum')), + 'additional' => \@description, + } ); +} + +</%init> diff --git a/httemplate/edit/process/quick-cust_pkg.cgi b/httemplate/edit/process/quick-cust_pkg.cgi new file mode 100644 index 000000000..9c2474330 --- /dev/null +++ b/httemplate/edit/process/quick-cust_pkg.cgi @@ -0,0 +1,63 @@ +%if ($error) { +% $cgi->param('error', $error); +<% $cgi->redirect(popurl(3). 'misc/order_pkg.html?'. $cgi->query_string ) %> +%} else { +% my $frag = "cust_pkg". $cust_pkg->pkgnum; +<% header('Package ordered') %> + <SCRIPT TYPE="text/javascript"> + // XXX fancy ajax rebuild table at some point, but a page reload will do for now + + // XXX chop off trailing #target and replace... ? + window.top.location = '<% popurl(3). "view/cust_main.cgi?keywords=$custnum;fragment=$frag#$frag" %>'; + + </SCRIPT> + + </BODY></HTML> +%} +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Order customer package'); + +#untaint custnum (probably not necessary, searching for it is escape enough) +$cgi->param('custnum') =~ /^(\d+)$/ + or die 'illegal custnum '. $cgi->param('custnum'); +my $custnum = $1; +my $cust_main = qsearchs({ + 'table' => 'cust_main', + 'hashref' => { 'custnum' => $custnum }, + 'extra_sql' => ' AND '. $FS::CurrentUser::CurrentUser->agentnums_sql, +}); +die 'unknown custnum' unless $cust_main; + +#probably not necessary, taken care of by cust_pkg::check +$cgi->param('pkgpart') =~ /^(\d+)$/ + or die 'illegal pkgpart '. $cgi->param('pkgpart'); +my $pkgpart = $1; +$cgi->param('refnum') =~ /^(\d*)$/ + or die 'illegal refnum '. $cgi->param('refnum'); +my $refnum = $1; +$cgi->param('locationnum') =~ /^(\-?\d*)$/ + or die 'illegal locationnum '. $cgi->param('locationnum'); +my $locationnum = $1; + +my $cust_pkg = new FS::cust_pkg { + 'custnum' => $custnum, + 'pkgpart' => $pkgpart, + 'refnum' => $refnum, + 'locationnum' => $locationnum, +}; + +my %opt = ( 'cust_pkg' => $cust_pkg ); + +if ( $locationnum == -1 ) { + my $cust_location = new FS::cust_location { + map { $_ => scalar($cgi->param($_)) } + qw( custnum address1 address2 city county state zip country ) + }; + $opt{'cust_location'} = $cust_location; +} + +my $error = $cust_main->order_pkg( %opt ); + +</%init> diff --git a/httemplate/edit/process/rate.cgi b/httemplate/edit/process/rate.cgi new file mode 100755 index 000000000..48d9322ca --- /dev/null +++ b/httemplate/edit/process/rate.cgi @@ -0,0 +1,9 @@ +<% $server->process %> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $server = new FS::UI::Web::JSRPC 'FS::rate::process', $cgi; + +</%init> diff --git a/httemplate/edit/process/rate_detail.html b/httemplate/edit/process/rate_detail.html new file mode 100644 index 000000000..6200d615f --- /dev/null +++ b/httemplate/edit/process/rate_detail.html @@ -0,0 +1,13 @@ +<% include( 'elements/process.html', + 'table' => 'rate_detail', + 'popup_reload' => 'Rate changed', #a popup "parent reload" for now + #someday change the individual element and go away instead + ) +%> +<%init> + +my $conf = new FS::Conf; +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +</%init> diff --git a/httemplate/edit/process/rate_region.cgi b/httemplate/edit/process/rate_region.cgi new file mode 100755 index 000000000..882991e9d --- /dev/null +++ b/httemplate/edit/process/rate_region.cgi @@ -0,0 +1,57 @@ +%if ( $error ) { +% $cgi->param('error', $error); +<% $cgi->redirect(popurl(2). "rate_region.cgi?". $cgi->query_string ) %> +%} else { +<% $cgi->redirect(popurl(3). "browse/rate_region.html") %> +%} +<%init> + +my $conf = new FS::Conf; +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $regionnum = $cgi->param('regionnum'); + +my $old = qsearchs('rate_region', { 'regionnum' => $regionnum } ) if $regionnum; + +my $new = new FS::rate_region ( { + map { + $_, scalar($cgi->param($_)); + } ( fields('rate_region') ) +} ); + +my $countrycode = $cgi->param('countrycode'); +my @npa = split(/\s*,\s*/, $cgi->param('npa')); +$npa[0] = '' unless @npa; +my @rate_prefix = map { + #my($npa,$nxx) = split('-', $_); + s/\D//g; + new FS::rate_prefix { + 'countrycode' => $countrycode, + #'npa' => $npa, + #'nxx' => $nxx, + 'npa' => $_, + } + } @npa; + +my @dest_detail = map { + my $ratenum = $_->ratenum; + new FS::rate_detail { + 'ratenum' => $ratenum, + map { $_ => $cgi->param("$_$ratenum") } + qw( min_included min_charge sec_granularity classnum ) + }; +} qsearch('rate', {} ); + + +my $error; +if ( $regionnum ) { + $error = $new->replace($old, 'rate_prefix' => \@rate_prefix, + 'dest_detail' => \@dest_detail, ); +} else { + $error = $new->insert( 'rate_prefix' => \@rate_prefix, + 'dest_detail' => \@dest_detail, ); + $regionnum = $new->getfield('regionnum'); +} + +</%init> diff --git a/httemplate/edit/process/reason.html b/httemplate/edit/process/reason.html new file mode 100644 index 000000000..cb79ed254 --- /dev/null +++ b/httemplate/edit/process/reason.html @@ -0,0 +1,12 @@ +<% include( 'elements/process.html', + 'table' => 'reason', + 'redirect' => popurl(3) . 'browse/reason.html?class=' . + $cgi->param('class') . '&', + ) +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +</%init> diff --git a/httemplate/edit/process/reason_type.html b/httemplate/edit/process/reason_type.html new file mode 100644 index 000000000..3172b27c4 --- /dev/null +++ b/httemplate/edit/process/reason_type.html @@ -0,0 +1,12 @@ +<% include( 'elements/process.html', + 'table' => 'reason_type', + 'redirect' => popurl(3) . 'browse/reason_type.html?class=' . + $cgi->param('class') . '&', + ) +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +</%init> diff --git a/httemplate/edit/process/reg_code.cgi b/httemplate/edit/process/reg_code.cgi new file mode 100644 index 000000000..035e10b90 --- /dev/null +++ b/httemplate/edit/process/reg_code.cgi @@ -0,0 +1,45 @@ +%unless ( ref($error) ) { +% $cgi->param('error'. $error ); +<% $cgi->redirect(popurl(3). "edit/reg_code.cgi?". $cgi->query_string ) %> +% } else { + +<% include("/elements/header.html","$num registration codes generated for ". $agent->agent, menubar( + 'View all agents' => popurl(3). 'browse/agent.cgi', +) ) %> + +<PRE><FONT SIZE="+1"> +% foreach my $code ( @$error ) { + <% $code %> +% } +</FONT></PRE> + +<% include('/elements/footer.html') %> +% } +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +$cgi->param('agentnum') =~ /^(\d+)$/ + or errorpage('illegal agentnum '. $cgi->param('agentnum')); +my $agentnum = $1; +my $agent = qsearchs('agent', { 'agentnum' => $agentnum } ); + +my $error = ''; + +my $num = 0; +if ( $cgi->param('num') =~ /^\s*(\d+)\s*$/ ) { + $num = $1; +} else { + $error = 'Illegal number of codes: '. $cgi->param('num'); +} + +my @pkgparts = + map { /^pkgpart(.*)$/; $1 } + grep { $cgi->param($_) } + grep { /^pkgpart/ } + $cgi->param; + +$error ||= $agent->generate_reg_codes($num, \@pkgparts); + +</%init> diff --git a/httemplate/edit/process/router.cgi b/httemplate/edit/process/router.cgi new file mode 100644 index 000000000..3cbb8c58e --- /dev/null +++ b/httemplate/edit/process/router.cgi @@ -0,0 +1,20 @@ +<% include('elements/process.html', + 'table' => 'router', + 'viewall_dir' => 'browse', + 'viewall_ext' => 'cgi', + 'edit_ext' => 'cgi', + 'process_m2m' => { 'link_table' => 'part_svc_router', + 'target_table' => 'part_svc', + }, + 'agent_virt' => 1, + 'agent_null_right' => 'Broadband global configuration', + ) +%> +<%init> +my $curuser = $FS::CurrentUser::CurrentUser; + +die "access denied" + unless $curuser->access_right('Broadband configuration') + || $curuser->access_right('Broadband global configuration'); + +</%init> diff --git a/httemplate/edit/process/svc_Common.html b/httemplate/edit/process/svc_Common.html new file mode 100644 index 000000000..cf5f01f71 --- /dev/null +++ b/httemplate/edit/process/svc_Common.html @@ -0,0 +1,16 @@ +<% include( 'elements/svc_Common.html', + 'table' => $table, + 'redirect' => popurl(3)."view/svc_Common.html?svcdb=$table;svcnum=", + 'error_redirect' => popurl(3)."edit/svc_Common.html?svcdb=$table;", + ) +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Provision customer service'); #something else more specific? + +$cgi->param('svcdb') =~ /^(svc_\w+)$/ or die "unparsable svcdb"; +my $table = $1; +require "FS/$table.pm"; + +</%init> diff --git a/httemplate/edit/process/svc_acct.cgi b/httemplate/edit/process/svc_acct.cgi new file mode 100755 index 000000000..0a89e253c --- /dev/null +++ b/httemplate/edit/process/svc_acct.cgi @@ -0,0 +1,64 @@ +%if ( $error ) { +% $cgi->param('error', $error); +<% $cgi->redirect(popurl(2). "svc_acct.cgi?". $cgi->query_string ) %> +%} else { +<% $cgi->redirect(popurl(3). "view/svc_acct.cgi?" . $svcnum ) %> +%} +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Provision customer service'); #something else more specific? + +$cgi->param('svcnum') =~ /^(\d*)$/ or die "Illegal svcnum!"; +my $svcnum = $1; + +my $old; +if ( $svcnum ) { + $old = qsearchs('svc_acct', { 'svcnum' => $svcnum } ) + or die "fatal: can't find account (svcnum $svcnum)!"; +} else { + $old = ''; +} + +#unmunge popnum +$cgi->param('popnum', (split(/:/, $cgi->param('popnum') ))[0] ); + +#unmunge passwd +if ( $cgi->param('_password') eq '*HIDDEN*' ) { + die "fatal: no previous account to recall hidden password from!" unless $old; + $cgi->param('_password',$old->getfield('_password')); +} + +#unmunge usergroup +$cgi->param('usergroup', [ $cgi->param('radius_usergroup') ] ); + +#unmunge bytecounts +foreach (map { $_,$_."_threshold" } qw( upbytes downbytes totalbytes )) { + $cgi->param($_, FS::UI::bytecount::parse_bytecount($cgi->param($_)) ); +} + +my %hash = $svcnum ? $old->hash : (); +map { + $hash{$_} = scalar($cgi->param($_)); + #} qw(svcnum pkgnum svcpart username _password popnum uid gid finger dir + # shell quota slipip) + } (fields('svc_acct'), qw ( pkgnum svcpart usergroup )); +my $new = new FS::svc_acct ( \%hash ); + +my $error; +if ( $svcnum ) { + foreach (grep { $old->$_ != $new->$_ } qw( seconds upbytes downbytes totalbytes )) { + my %hash = map { $_ => $new->$_ } + grep { $new->$_ } + qw( seconds upbytes downbytes totalbytes ); + + $error = $new->set_usage(\%hash); #unoverlimit and trigger radius changes + last; #once is enough + } + $error ||= $new->replace($old); +} else { + $error = $new->insert; + $svcnum = $new->svcnum; +} + +</%init> diff --git a/httemplate/edit/process/svc_acct_pop.cgi b/httemplate/edit/process/svc_acct_pop.cgi new file mode 100755 index 000000000..6e823a824 --- /dev/null +++ b/httemplate/edit/process/svc_acct_pop.cgi @@ -0,0 +1,33 @@ +%if ( $error ) { +% $cgi->param('error', $error); +<% $cgi->redirect(popurl(2). "svc_acct_pop.cgi?". $cgi->query_string ) %> +%} else { +<% $cgi->redirect(popurl(3). "browse/svc_acct_pop.cgi") %> +%} +<%init> + +my $curuser = $FS::CurrentUser::CurrentUser; + +die "access denied" + unless $curuser->access_right('Dialup configuration') + || $curuser->access_right('Dialup global configuration'); + +my $popnum = $cgi->param('popnum'); + +my $old = qsearchs('svc_acct_pop',{'popnum'=>$popnum}) if $popnum; + +my $new = new FS::svc_acct_pop ( { + map { + $_, scalar($cgi->param($_)); + } fields('svc_acct_pop') +} ); + +my $error = ''; +if ( $popnum ) { + $error = $new->replace($old); +} else { + $error = $new->insert; + $popnum=$new->getfield('popnum'); +} + +</%init> diff --git a/httemplate/edit/process/svc_broadband.cgi b/httemplate/edit/process/svc_broadband.cgi new file mode 100644 index 000000000..d5c9820bb --- /dev/null +++ b/httemplate/edit/process/svc_broadband.cgi @@ -0,0 +1,8 @@ +<% include('elements/svc_Common.html', 'table' => 'svc_broadband') %> +<%init> +my $curuser = $FS::CurrentUser::CurrentUser; + +die "access denied" + unless $curuser->access_right('Provision customer service'); #something else more specific? + +</%init> diff --git a/httemplate/edit/process/svc_domain.cgi b/httemplate/edit/process/svc_domain.cgi new file mode 100755 index 000000000..9993a879e --- /dev/null +++ b/httemplate/edit/process/svc_domain.cgi @@ -0,0 +1,33 @@ +%if ($error) { +% $cgi->param('error', $error); +<% $cgi->redirect(popurl(2). "svc_domain.cgi?". $cgi->query_string ) %> +%} else { +<% $cgi->redirect(popurl(3). "view/svc_domain.cgi?$svcnum") %> +%} +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Provision customer service'); #something else more specific? + +#remove this to actually test the domains! +$FS::svc_domain::whois_hack = 1; + +$cgi->param('svcnum') =~ /^(\d*)$/ or die "Illegal svcnum!"; +my $svcnum = $1; + +my $new = new FS::svc_domain ( { + map { + $_, scalar($cgi->param($_)); + #} qw(svcnum pkgnum svcpart domain action purpose) + } ( fields('svc_domain'), qw( pkgnum svcpart action purpose ) ) +} ); + +my $error = ''; +if ($cgi->param('svcnum')) { + $error="Can't modify a domain!"; +} else { + $error=$new->insert; + $svcnum=$new->svcnum; +} + +</%init> diff --git a/httemplate/edit/process/svc_external.cgi b/httemplate/edit/process/svc_external.cgi new file mode 100755 index 000000000..673e5a5a0 --- /dev/null +++ b/httemplate/edit/process/svc_external.cgi @@ -0,0 +1,31 @@ +%if ($error) { +% $cgi->param('error', $error); +<% $cgi->redirect(popurl(2). "svc_external.cgi?". $cgi->query_string ) %> +%} else { +<% $cgi->redirect(popurl(3). "view/svc_external.cgi?$svcnum") %> +%} +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Provision customer service'); #something else more specific? + +$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'); +} + +</%init> diff --git a/httemplate/edit/process/svc_forward.cgi b/httemplate/edit/process/svc_forward.cgi new file mode 100755 index 000000000..fffad84d6 --- /dev/null +++ b/httemplate/edit/process/svc_forward.cgi @@ -0,0 +1,31 @@ +%if ($error) { +% $cgi->param('error', $error); +<% $cgi->redirect(popurl(2). "svc_forward.cgi?". $cgi->query_string ) %> +%} else { +<% $cgi->redirect(popurl(3). "view/svc_forward.cgi?$svcnum") %> +%} +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Provision customer service'); #something else more specific? + +$cgi->param('svcnum') =~ /^(\d*)$/ or die "Illegal svcnum!"; +my $svcnum =$1; + +my $old = qsearchs('svc_forward',{'svcnum'=>$svcnum}) if $svcnum; + +my $new = new FS::svc_forward ( { + map { + ($_, scalar($cgi->param($_))); + } ( fields('svc_forward'), qw( pkgnum svcpart ) ) +} ); + +my $error = ''; +if ( $svcnum ) { + $error = $new->replace($old); +} else { + $error = $new->insert; + $svcnum = $new->getfield('svcnum'); +} + +</%init> diff --git a/httemplate/edit/process/svc_phone.html b/httemplate/edit/process/svc_phone.html new file mode 100644 index 000000000..27a703cdf --- /dev/null +++ b/httemplate/edit/process/svc_phone.html @@ -0,0 +1,10 @@ +<% include( 'elements/svc_Common.html', + 'table' => 'svc_phone', + ) +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Provision customer service'); #something else more specific? + +</%init> diff --git a/httemplate/edit/process/svc_www.cgi b/httemplate/edit/process/svc_www.cgi new file mode 100644 index 000000000..f02d25305 --- /dev/null +++ b/httemplate/edit/process/svc_www.cgi @@ -0,0 +1,38 @@ +%if ( $error ) { +% $cgi->param('error', $error); +<% $cgi->redirect(popurl(2). "svc_www.cgi?". $cgi->query_string ) %> +%} else { +<% $cgi->redirect(popurl(3). "view/svc_www.cgi?" . $svcnum ) %> +%} +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Provision customer service'); #something else more specific? + +$cgi->param('svcnum') =~ /^(\d*)$/ or die "Illegal svcnum!"; +my $svcnum = $1; + +my $old; +if ( $svcnum ) { + $old = qsearchs('svc_www', { 'svcnum' => $svcnum } ) + or die "fatal: can't find website (svcnum $svcnum)!"; +} else { + $old = ''; +} + +my $new = new FS::svc_www ( { + map { + ($_, scalar($cgi->param($_))); + #} qw(svcnum pkgnum svcpart recnum usersvc) + } ( fields('svc_www'), qw( pkgnum svcpart ) ) +} ); + +my $error; +if ( $svcnum ) { + $error = $new->replace($old); +} else { + $error = $new->insert; + $svcnum = $new->svcnum; +} + +</%init> diff --git a/httemplate/edit/process/tax_class.html b/httemplate/edit/process/tax_class.html new file mode 100644 index 000000000..339c9083e --- /dev/null +++ b/httemplate/edit/process/tax_class.html @@ -0,0 +1,49 @@ +% if ( $error ) { +% $cgi->param('error', $error); +<% $cgi->redirect(popurl(2). "tax_class.html?". $cgi->query_string ) %> +%} else { +<% $cgi->redirect(popurl(3). "browse/tax_rate.cgi?taxclassnum=". uri_escape($tax_class->taxclassnum) ) %> +%} +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $tax_class = new FS::tax_class { + 'taxclass' => $cgi->param('taxclass'), + 'description' => $cgi->param('description'), +}; + +#maybe this whole thing should be in a transaction. at some point, no biggie +#none of the follow-up stuff will fail unless there's a more serious problem +#than a hanging record in tax_class... + +my $error = $tax_class->insert; + +# all of this is highly dubious at the moment + +#unless ( $error ) { +# #auto-add the new taxclass to any regions that have taxclasses already +# +# my $sth = dbh->prepare(" +# SELECT geocode FROM tax_rate +# WHERE taxclass IS NOT NULL AND taxclass != '' +# GROUP BY geocode +# ") or die dbh->errstr; +# $sth->execute or die $sth->errstr; +# +# while ( my $row = $sth->fetchrow_hashref ) { +# warn "inserting for $row"; +# my $cust_main_county = new FS::tax_rate { +# 'geocode' => $row->{geocode}, +# 'tax' => 0, +# 'taxclassnum' => $tax_class->taxclassnum, +# }; +# $error = $cust_main_county->insert; +# #last if $error; +# die $error if $error; +# } +# +#} + +</%init> diff --git a/httemplate/edit/process/tax_rate.html b/httemplate/edit/process/tax_rate.html new file mode 100644 index 000000000..431e54264 --- /dev/null +++ b/httemplate/edit/process/tax_rate.html @@ -0,0 +1,22 @@ +<% include( 'elements/process.html', + 'table' => 'tax_rate', + 'value_callback' => $value_callback, + 'popup_reload' => 'Tax changed', #a popup "parent reload" for now + #someday change the individual element and go away instead + ) +%> +<%once> + +my $value_callback = sub { my ($field, $value) = @_; + ($field =~ /^(tax|excessrate|usetax|useexcessrate)$/) + ? $value/100 + : $value + }; +</%once> +<%init> + +my $conf = new FS::Conf; +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +</%init> diff --git a/httemplate/edit/process/usage_class.html b/httemplate/edit/process/usage_class.html new file mode 100644 index 000000000..cf50cb762 --- /dev/null +++ b/httemplate/edit/process/usage_class.html @@ -0,0 +1,11 @@ +<% include( 'elements/process.html', + 'table' => 'usage_class', + 'viewall_dir' => 'browse', + ) +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +</%init> |