diff options
Diffstat (limited to 'httemplate/edit/process')
79 files changed, 3401 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..22aab44e8 --- /dev/null +++ b/httemplate/edit/process/REAL_cust_pkg.cgi @@ -0,0 +1,54 @@ +%if ( $error ) { +%  $cgi->param('error', $error); +<% $cgi->redirect(popurl(2). "REAL_cust_pkg.cgi?". $cgi->query_string ) %> +%} else {  +%  my $custnum = $new->custnum; +%  my $show = $curuser->default_customer_view =~ /^(jumbo|packages)$/ +%               ? '' +%               : ';show=packages'; +%  my $frag = "cust_pkg$pkgnum"; #hack for IE ignoring real #fragment +<% $cgi->redirect(popurl(3). "view/cust_main.cgi?custnum=$custnum$show;fragment=$frag#$frag" ) %> +%} +<%init> + +my $curuser = $FS::CurrentUser::CurrentUser; + +die "access denied" +  unless $curuser->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{'start_date'} = $cgi->param('start_date') ? str2time($cgi->param('start_date')) : ''; +$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 @errors = (); + +push @errors, '_bill_areyousure' +  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 + +push @errors, '_setup_areyousure' +  if ! $hash{'setup'} && $old->setup         # if the setup date was removed +  && ! $cgi->param('setup_areyousure');      # and it wasn't confirmed  + +push @errors, '_start' +  if $hash{'start_date'} && $old->start_date # if a start date was added +  && $hash{'setup'};                         # but there's a setup date + +my $new; +my $error; +if ( @errors ) { +  $error = join(',', @errors); +} 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..af9e49500 --- /dev/null +++ b/httemplate/edit/process/bulk-cust_main_county.html @@ -0,0 +1,66 @@ +% if ( $error ) { #better to redirect back to  +%# <% $cgi->redirect("$url?". $cgi->query_string ) %> +  <% include('/elements/header-popup.html', "Error ${action}ing taxes" ) %> + +  <FONT SIZE="+1" COLOR="#ff0000">Error: <% $error |h %></FONT> +  <BR><BR> + +  </BODY> +  </HTML> + +% } else { +  <% include('/elements/header-popup.html', "Taxes ${action}ed") %> + +  <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); + +$cgi->param('action') =~ /^(add|edit)$/ or die "unknown action"; +my $action = $1; + +my $error = ''; +foreach my $taxnum ( @taxnum ) { + +  my $cust_main_county = qsearchs('cust_main_county', { 'taxnum' => $taxnum } ) +    or die "unknown taxnum: $taxnum"; + +  if ( $action eq 'edit' || $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_category.html b/httemplate/edit/process/cust_category.html new file mode 100644 index 000000000..c3a880944 --- /dev/null +++ b/httemplate/edit/process/cust_category.html @@ -0,0 +1,11 @@ +<% include( 'elements/process.html', +               'table'       => 'cust_category', +               'viewall_dir' => 'browse', +           ) +%> +<%init> + +die "access denied" +  unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +</%init> diff --git a/httemplate/edit/process/cust_class.html b/httemplate/edit/process/cust_class.html new file mode 100644 index 000000000..3f63ea4b3 --- /dev/null +++ b/httemplate/edit/process/cust_class.html @@ -0,0 +1,11 @@ +<% include( 'elements/process.html', +               'table'       => 'cust_class', +               'viewall_dir' => 'browse', +           ) +%> +<%init> + +die "access denied" +  unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +</%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..d3847dc40 --- /dev/null +++ b/httemplate/edit/process/cust_credit_bill.cgi @@ -0,0 +1,19 @@ +<% 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'); + +if ( $cgi->param('src_amount') ) { +  die "access denied" +    unless ( $FS::CurrentUser::CurrentUser->access_right('Post credit') && +           $FS::CurrentUser::CurrentUser->access_right('Delete 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..f72ca0a81 --- /dev/null +++ b/httemplate/edit/process/cust_main.cgi @@ -0,0 +1,260 @@ +% 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 $conf = new FS::Conf; + +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 %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 +  ); +} + +my %usedatetime = ( 'birthdate' => 1 ); + +foreach my $dfield (qw( birthdate signupdate )) { + +  if ( $cgi->param($dfield) && $cgi->param($dfield) =~ /^([ 0-9\-\/]{0,10})$/) { + +    my $value = $1; +    my $parsed = ''; + +    if ( exists $usedatetime{$dfield} && $usedatetime{$dfield} ) { + +      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($value); +      if ( $dt ) { +        $parsed = $dt->epoch; +      } else { +    #    $error ||= $cgi->param('birthdate') . " is an invalid birthdate:" . $parser->errmsg; +        $error ||= "Invalid $dfield: $value"; +      } + +    } else { + +      $parsed = str2time($value) +        or $error ||= "Invalid $dfield: $value"; + +    } + +    $new->setfield( $dfield, $parsed ); +    $cgi->param(    $dfield, $parsed ); + +  } + +} + +$new->setfield('paid', $cgi->param('paid') ) +  if $cgi->param('paid'); + +my @exempt_groups = grep /\S/, $conf->config('tax-cust_exempt-groups'); +my @tax_exempt = grep { $cgi->param("tax_$_") eq 'Y' } @exempt_groups; + +#perhaps this stuff should go to cust_main.pm +if ( $new->custnum eq '' ) { + +  my $cust_pkg = ''; +  my $svc; + +  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); +    my $part_pkg = qsearchs('part_pkg', { 'pkgpart' => $pkgpart } ); +    #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 }); + +    if ( $agent ) { +      # $pkgpart_href->{PKGPART} is true iff $custnum may purchase $pkgpart +      my $pkgpart_href = $agent->pkgpart_hashref +        if $agent; +      #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 } +            || $agent->agentnum == $part_pkg->agentnum; +    } else { +      $error = 'Select agent'; +    } + +    $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 $part_svc = qsearchs('part_svc', { 'svcpart' => $svcpart } ); +    my $svcdb = $part_svc->svcdb; + +    if ( $svcdb eq 'svc_acct' ) { + +      my %svc_acct = ( +                       'svcpart'   => $svcpart, +                       'username'  => scalar($cgi->param('username')), +                       '_password' => scalar($cgi->param('_password')), +                       'popnum'    => scalar($cgi->param('popnum')), +                     ); +      $svc_acct{'domsvc'} = $cgi->param('domsvc') +        if $cgi->param('domsvc'); + +      $svc = new FS::svc_acct \%svc_acct; + +      #and just in case you were silly +      $svc->svcpart($svcpart); +      $svc->username($cgi->param('username')); +      $svc->_password($cgi->param('_password')); +      $svc->popnum($cgi->param('popnum')); + +    } elsif ( $svcdb eq 'svc_phone' ) { + +      my %svc_phone = ( +                        'svcpart' => $svcpart, +                        map { $_ => scalar($cgi->param($_)) } +                          qw( countrycode phonenum sip_password pin phone_name ) +                      ); + +      $svc = new FS::svc_phone \%svc_phone; + +    } else { +      die "$svcdb not handled on new customer yet"; +    } + +    #$error ||= $svc_acct->check; + +  } + +  use Tie::RefHash; +  tie my %hash, 'Tie::RefHash'; +  %hash = ( $cust_pkg => [ $svc ] ) if $cust_pkg; +  $error ||= $new->insert( \%hash, \@invoicing_list, +                           'tax_exemption' => \@tax_exempt, +                         ); + +  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, +                            'tax_exemption' => \@tax_exempt, +                          ); + +  warn "$me returned from replace" if $DEBUG; +   +} + +</%init> diff --git a/httemplate/edit/process/cust_main_attach.cgi b/httemplate/edit/process/cust_main_attach.cgi new file mode 100644 index 000000000..092714122 --- /dev/null +++ b/httemplate/edit/process/cust_main_attach.cgi @@ -0,0 +1,101 @@ +%if ($error) { +%  $cgi->param('error', $error); +<% $cgi->redirect(popurl(2). 'cust_main_attach.cgi?'. $cgi->query_string ) %> +%} else { +% my $act = 'added'; +% $act = 'updated' if ($attachnum); +% $act = 'purged' if($attachnum and $purge); +% $act = 'undeleted' if($attachnum and $undelete); +% $act = 'deleted' if($attachnum and $delete); +<% header('Attachment ' . $act ) %> +    <SCRIPT TYPE="text/javascript"> +      window.top.location.reload(); +    </SCRIPT> +    </BODY></HTML> +% } +<%init> + +my $error; +$cgi->param('custnum') =~ /^(\d+)$/ +  or die "Illegal custnum: ". $cgi->param('custnum'); +my $custnum = $1; + +$cgi->param('attachnum') =~ /^(\d*)$/ +  or die "Illegal attachnum: ". $cgi->param('attachnum'); +my $attachnum = $1; + +my $curuser = $FS::CurrentUser::CurrentUser; +my $otaker = $curuser->name; +$otaker = $curuser->username if ($otaker eq "User, Legacy"); + +my $delete = $cgi->param('delete'); +my $undelete = $cgi->param('undelete'); +my $purge = $cgi->param('purge'); + +my $new = new FS::cust_attachment ( { +  attachnum => $attachnum, +  custnum   => $custnum, +  _date     => time, +  otaker    => $otaker, +  disabled  => '', +}); +my $old; + +if($attachnum) { +  $old = qsearchs('cust_attachment', { attachnum => $attachnum }); +  if(!$old) { +    $error = "Attachnum '$attachnum' not found"; +  } +  elsif($purge) { # do nothing +  } +  else { +    map { $new->$_($old->$_) }  +      ('_date', 'otaker', 'body', 'disabled'); +    $new->filename($cgi->param('filename') || $old->filename); +    $new->mime_type($cgi->param('mime_type') || $old->mime_type); +    $new->title($cgi->param('title')); +    if($delete and not $old->disabled) { +      $new->disabled(time); +    } +    if($undelete and $old->disabled) { +      $new->disabled(''); +    } +  } +} +else { # This is a new attachment, so require a file. + +  my $filename = $cgi->param('file'); +  if($filename) { +    $new->filename($filename); +    $new->mime_type($cgi->uploadInfo($filename)->{'Content-Type'}); +    $new->title($cgi->param('title')); +     +    local $/; +    my $fh = $cgi->upload('file'); +    $new->body(<$fh>); +  } +  else { +    $error = 'No file uploaded'; +  } +} +my $action = 'Add'; +$action = 'Edit' if $attachnum; +$action = 'Delete' if $attachnum and $delete; +$action = 'Undelete' if $attachnum and $undelete; +$action = 'Purge' if $attachnum and $purge; + +$error = 'access denied' unless $curuser->access_right($action . ' attachment'); + +if(!$error) { +  if($old and $old->disabled and $purge) { +    $error = $old->delete; +  } +  elsif($old) { +    $error = $new->replace($old); +  } +  else { +    $error = $new->insert; +  } +} + +</%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..9608fc919 --- /dev/null +++ b/httemplate/edit/process/cust_main_county-collapse.cgi @@ -0,0 +1,46 @@ +<% $cgi->redirect(popurl(3). "browse/cust_main_county.cgi") %> +<%init> + +die "access denied" +  unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +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 + +my %search = ( +               'country' => $cust_main_county->country, +               'state'   => $cust_main_county->state, +             ); + +$search{'county'} = $cust_main_county->county +  if $cust_main_county->city; + +foreach my $delete ( qsearch('cust_main_county', \%search) ) { +#  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(''); +if ( $cust_main_county->city ) { +  $cust_main_county->city(''); +} else { +  $cust_main_county->county(''); +} +my $error = $cust_main_county->insert; +die $error if $error; + +</%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..9984b08fa --- /dev/null +++ b/httemplate/edit/process/cust_main_county-expand.cgi @@ -0,0 +1,83 @@ +<% 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',$_); +  } elsif ( ! $cust_main_county->county ) { +    $new->setfield('county',$_); +  } else { +    #uppercase cities in the US to try and agree with USPS validation +    $new->setfield('city', $new->country eq 'US' ? uc($_) : $_ ); +  } +  my $error = $new->insert; +  die $error if $error; +} + +unless ( qsearch( 'cust_main', { +                                 'city'    => $cust_main_county->city, +                                 'county'  => $cust_main_county->county, +                                 'state'   => $cust_main_county->state, +                                 '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?". +                         'city='.    uri_escape($cust_main_county->city   ).';'. +                         'county='.  uri_escape($cust_main_county->county ).';'. +                         'state='.   uri_escape($cust_main_county->state  ).';'. +                         '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..a310c5306 --- /dev/null +++ b/httemplate/edit/process/cust_pay.cgi @@ -0,0 +1,57 @@ +%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( 'manual' => 1 ); +%  } +%  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 +        pkgnum +      ) +  #} 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/cust_tax_adjustment.html b/httemplate/edit/process/cust_tax_adjustment.html new file mode 100644 index 000000000..204b5b9f7 --- /dev/null +++ b/httemplate/edit/process/cust_tax_adjustment.html @@ -0,0 +1,41 @@ +% if ( $error ) { +%   $cgi->param('error', $error ); +<% $cgi->redirect($p.'cust_tax_adjustment.html?'. $cgi->query_string) %> +% } else { +<% header("Tax adjustment added") %> +  <SCRIPT TYPE="text/javascript"> +    //window.top.location.reload(); +    parent.cClick(); +  </SCRIPT> +  </BODY></HTML> +% } +<%init> + +die "access denied" +  unless $FS::CurrentUser::CurrentUser->access_right('Add customer tax adjustment'); + +my $error = ''; +my $conf = new FS::conf; +my $param = $cgi->Vars; + +$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; + +unless ( $error ) { + +  my $cust_tax_adjustment = new FS::cust_tax_adjustment { +    'custnum' => $custnum, +    'taxname' => $param->{'taxname'}, +    'amount'  => $amount, +    'comment' => $param->{'comment'}, +  }; +  $error = $cust_tax_adjustment->insert; + +} + +</%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/domreg.cgi b/httemplate/edit/process/domreg.cgi new file mode 100755 index 000000000..a95474e44 --- /dev/null +++ b/httemplate/edit/process/domreg.cgi @@ -0,0 +1,62 @@ +%if ($error) { +%  $cgi->param('error', $error); +%    errorpage($error); +%} 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? + +$cgi->param('op') =~ /^(register|transfer|revoke|renew)$/ or die "Illegal operation"; +my $operation = $1; +#my($query) = $cgi->keywords; +#$query =~ /^(\d+)$/; +$cgi->param('svcnum') =~ /^(\d*)$/ or die "Illegal svcnum!"; +my $svcnum = $1; +my $svc_domain = qsearchs({ +  'select'    => 'svc_domain.*', +  'table'     => 'svc_domain', +  'addl_from' => ' LEFT JOIN cust_svc  USING ( svcnum  ) '. +                 ' LEFT JOIN cust_pkg  USING ( pkgnum  ) '. +                 ' LEFT JOIN cust_main USING ( custnum ) ', +  'hashref'   => {'svcnum'=>$svcnum}, +  'extra_sql' => ' AND '. $FS::CurrentUser::CurrentUser->agentnums_sql, +}); +die "Unknown svcnum" unless $svc_domain; + +my $cust_svc = qsearchs('cust_svc',{'svcnum'=>$svcnum}); +my $part_svc = qsearchs('part_svc',{'svcpart'=> $cust_svc->svcpart } ); +die "Unknown svcpart" unless $part_svc; + +my $error = ''; + +my @exports = $part_svc->part_export(); + +my $registrar; +my $export; + +# Find the first export that does domain registration +foreach (@exports) { +	$export = $_ if $_->can('registrar'); +} + +my $period = 1; # Current OpenSRS export can only handle 1 year registrations + +# If we have a domain registration export, get the registrar object +if ($export) { +	if ($operation eq 'register') { +		$error = $export->register( $svc_domain, $period ); +	} elsif ($operation eq 'transfer') { +		$error = $export->transfer( $svc_domain ); +	} elsif ($operation eq 'revoke') { +		$error = $export->revoke( $svc_domain ); +	} elsif ($operation eq 'renew') { +		$cgi->param('period') =~ /^(\d+)$/ or die "Illegal renewal period!"; +		$period = $1; +		$error = $export->renew( $svc_domain, $period ); +	} +} + +</%init> diff --git a/httemplate/edit/process/elements/ApplicationCommon.html b/httemplate/edit/process/elements/ApplicationCommon.html new file mode 100644 index 000000000..c7bdd3ea2 --- /dev/null +++ b/httemplate/edit/process/elements/ApplicationCommon.html @@ -0,0 +1,103 @@ +<%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 $error = ''; + +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 @subnames = grep { /.+/ } map { /^subnum(\d+)$/ ? $1 : '' } $cgi->param; +my @subitems = map { [ $cgi->param("subnum$_"), $cgi->param("subamount$_"), $cgi->param("taxXlocationnum$_") ] } +               @subnames; +{ local $^W = 0; @subitems = grep { $_->[1] + 0 } @subitems; } + +my %options = (); +$options{subitems} = \@subitems if scalar(@subitems); + +my $oldAutoCommit = $FS::UID::AutoCommit; +local $FS::UID::AutoCommit = 0; +my $dbh = dbh; +  +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 { + +  if ($src->amount != $cgi->param('src_amount')) { +    $src->amount($cgi->param('src_amount')); +    $error = $src->replace; +  } + +  my $class = 'FS::'. $opt{link_table}; + +  $new = $class->new( { +    map { +      $_ => scalar($cgi->param($_)); +    } fields($opt{link_table}) +  } ); + +#} + + +$options{manual} = 1; +$error ||= $new->insert( %options ); + +if ($error) { +  $dbh->rollback if $oldAutoCommit; +} else { +  $dbh->commit or die $dbh->errstr if $oldAutoCommit; +} +</%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_device.html b/httemplate/edit/process/part_device.html new file mode 100644 index 000000000..2b7e1da49 --- /dev/null +++ b/httemplate/edit/process/part_device.html @@ -0,0 +1,11 @@ +<% include( 'elements/process.html', +               'table'       => 'part_device', +               'viewall_dir' => 'browse', +           ) +%> +<%init> + +die "access denied" +  unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +</%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..209419f0b --- /dev/null +++ b/httemplate/edit/process/part_export.cgi @@ -0,0 +1,42 @@ +%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 @values = $cgi->param($_); +  my $value = scalar(@values) > 1 ? join (' ', @values) : $values[0]; +  $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..019224c4e --- /dev/null +++ b/httemplate/edit/process/part_pkg.cgi @@ -0,0 +1,222 @@ +<% 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 ); +        } +        grep { $_ !~ /^report_option_/ } +        @options; + +  foreach ( split(',', $cgi->param('taxproductnums') ) ) { +    my $value = $cgi->param("taxproductnum_$_"); +    $error ||= "Illegal taxproductnum_$_: $value" +      unless ( $value =~ /^\d*$/  ); +    $options{"usage_taxproductnum_$_"} = $value; +  } + +  foreach ( $cgi->param('report_option') ) { +    $error ||= "Illegal optional report class: $_" unless ( $_ =~ /^\d*$/  ); +    $options{"report_option_$_"} = 1; +  } + +  $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; +  my $show = $curuser->default_customer_view =~ /^(jumbo|packages)$/ +               ? '' +               : ';show=packages'; +  #my $frag = "cust_pkg$pkgnum"; #hack for IE ignoring real #fragment +  +  #can we link back to the specific customized package?  it would be nice... +  popurl(3). "view/cust_main.cgi?custnum=$custnum$show;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' => 'svc', 'hidden' => '' }, +    'params'       => [ map $cgi->param($_), +                        grep /^svc_dst_pkgpart/, $cgi->param +                      ], +  }, +  map {  +    my $hidden = $_; +    { 'link_table'   => 'part_pkg_link', +      'target_table' => 'part_pkg', +      'base_field'   => 'src_pkgpart', +      'target_field' => 'dst_pkgpart', +      'hashref'      => { 'link_type' => 'bill', 'hidden' => $hidden }, +      'params'       => [ map { $cgi->param($_) } +                          grep { my $param = "bill_dst_pkgpart__hidden"; +                                 my $digit = ''; +                                 (($digit) = /^bill_dst_pkgpart(\d+)/ ) && +                                 $cgi->param("$param$digit") eq $hidden; +                               } +                          $cgi->param +                        ], +    }, +  } ( '', 'Y' ), +); + +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_report_option.html b/httemplate/edit/process/part_pkg_report_option.html new file mode 100644 index 000000000..052aabd72 --- /dev/null +++ b/httemplate/edit/process/part_pkg_report_option.html @@ -0,0 +1,11 @@ +<% include( 'elements/process.html', +               'table'       => 'part_pkg_report_option', +               'viewall_dir' => 'browse', +           ) +%> +<%init> + +die "access denied" +  unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +</%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..b37279fb3 --- /dev/null +++ b/httemplate/edit/process/part_pkg_taxclass.html @@ -0,0 +1,17 @@ +<% include( 'elements/process.html', +              'table'    => 'part_pkg_taxclass', +              'redirect' => sub { +                my( $cgi, $part_pkg_taxclass ) = @_; + +                popurl(3). 'browse/cust_main_county.cgi?'. +                  'taxclass='. uri_escape($part_pkg_taxclass->taxclass). +                  ';dummy='; +              }, +          ) +%> +<%init> + +die "access denied" +  unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +</%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..812c988c5 --- /dev/null +++ b/httemplate/edit/process/payment_gateway.html @@ -0,0 +1,22 @@ +<% include( 'elements/process.html', +            'table'         => 'payment_gateway', +            'viewall_dir'   => 'browse', +            'args_callback' => $args_callback, +          ) +%> +<%init> + +die "access denied" +  unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $args_callback = sub { +  my ( $cgi, $new ) = @_; + +  my @options = split(/\r?\n/, $cgi->param('gateway_options') ); +  pop @options +    if scalar(@options) % 2 && $options[-1] =~ /^\s*$/; +  (@options) +}; + + +</%init> diff --git a/httemplate/edit/process/phone_device.html b/httemplate/edit/process/phone_device.html new file mode 100644 index 000000000..df9d5e793 --- /dev/null +++ b/httemplate/edit/process/phone_device.html @@ -0,0 +1,18 @@ +<% include( 'elements/process.html', +               'table'    => 'phone_device', +               'redirect' => sub { +                 my( $cgi, $phone_device ) = @_; +                 popurl(3).'view/svc_phone.cgi?'. +                   'svcnum='. $phone_device->svcnum. +                   ';devicenum='; +               }, +           ) +%> +<%init> + +# :/  needs agent-virt so you can't futz with arbitrary devices + +die "access denied" +  unless $FS::CurrentUser::CurrentUser->access_right('Provision customer service'); #something else more specific? + +</%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..827530e50 --- /dev/null +++ b/httemplate/edit/process/quick-charge.cgi @@ -0,0 +1,74 @@ +% 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, +    'bill_now'      => scalar($cgi->param('bill_now')), +    'invoice_terms' => scalar($cgi->param('invoice_terms')), +    'start_date'    => ( scalar($cgi->param('start_date')) +                           ? str2time($cgi->param('start_date')) +                           : '' +                       ), +    '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..7a0f08280 --- /dev/null +++ b/httemplate/edit/process/quick-cust_pkg.cgi @@ -0,0 +1,72 @@ +%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; +%  my $show = $curuser->default_customer_view =~ /^(jumbo|packages)$/ +%               ? '' +%               : ';show=packages'; +<% 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?custnum=$custnum$show;fragment=$frag#$frag" %>'; + +  </SCRIPT> + +  </BODY></HTML> +%} +<%init> + +my $curuser = $FS::CurrentUser::CurrentUser; + +die "access denied" +  unless $curuser->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, +  'start_date'  => ( scalar($cgi->param('start_date')) +                       ? str2time($cgi->param('start_date')) +                       : '' +                   ), +  '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..c19c2a51f --- /dev/null +++ b/httemplate/edit/process/svc_acct.cgi @@ -0,0 +1,67 @@ +%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> +use CGI::Carp; +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 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 ); + +$new->_password($old->_password) if $old; +if(  $cgi->param('clear_password') eq '*HIDDEN*' +  or $cgi->param('clear_password') =~ /^\(.* encrypted\)$/ ) { +  die "fatal: no previous account to recall hidden password from!" unless $old; +}  +else { +  $new->set_password($cgi->param('clear_password')); +} + +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..59b518097 --- /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) +  } ( fields('svc_domain'), qw( pkgnum svcpart action ) ) +} ); + +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> | 
