diff options
Diffstat (limited to 'httemplate')
| -rwxr-xr-x | httemplate/browse/part_pkg.cgi | 25 | ||||
| -rwxr-xr-x | httemplate/edit/cust_pay.cgi | 6 | ||||
| -rwxr-xr-x | httemplate/edit/part_pkg.cgi | 55 | ||||
| -rwxr-xr-x | httemplate/edit/process/cust_pay.cgi | 2 | ||||
| -rwxr-xr-x | httemplate/edit/process/part_pkg.cgi | 6 | ||||
| -rw-r--r-- | httemplate/elements/customer-table.html | 13 | ||||
| -rw-r--r-- | httemplate/elements/select-discount_term.html | 32 | ||||
| -rw-r--r-- | httemplate/elements/tr-select-discount_term.html | 25 | ||||
| -rw-r--r-- | httemplate/misc/batch-cust_pay.html | 98 | ||||
| -rw-r--r-- | httemplate/misc/payment.cgi | 5 | ||||
| -rw-r--r-- | httemplate/misc/process/batch-cust_pay.cgi | 13 | ||||
| -rw-r--r-- | httemplate/misc/process/payment.cgi | 26 | ||||
| -rw-r--r-- | httemplate/misc/xmlhttp-cust_main-discount_terms.cgi | 24 | ||||
| -rw-r--r-- | httemplate/view/cust_main/packages/package.html | 1 | 
14 files changed, 305 insertions, 26 deletions
| diff --git a/httemplate/browse/part_pkg.cgi b/httemplate/browse/part_pkg.cgi index 42eb5dfcb..3c3016ba2 100755 --- a/httemplate/browse/part_pkg.cgi +++ b/httemplate/browse/part_pkg.cgi @@ -195,6 +195,9 @@ push @fields, sub {    my $part_pkg = shift;    (my $plan = $plan_labels{$part_pkg->plan} ) =~ s/ / /g;    my $is_recur = ( $part_pkg->freq ne '0' ); +  my @discounts = sort { $a->months <=> $b->months } +                  map { $_->discount  } +                  $part_pkg->part_pkg_discount;    [      [ @@ -238,6 +241,28 @@ push @fields, sub {            }        $part_pkg->bill_part_pkg_link      ), +    ( scalar(@discounts) +        ?  [  +              { data => '<b>Discounts</b>', +                align=>'center', #? +                colspan=>2, +              } +            ] +        : ()   +    ), +    ( scalar(@discounts) +        ? map {  +            [  +              { data  => $_->months. ':', +                align => 'right', +              }, +              { data => $_->amount ? '$'. $_->amount : $_->percent. '%' +              } +            ] +          } +          @discounts +        : () +    ),    ];  #  $plan_labels{$part_pkg->plan}.'<BR>'. diff --git a/httemplate/edit/cust_pay.cgi b/httemplate/edit/cust_pay.cgi index cc4ec605d..7c4e6620e 100755 --- a/httemplate/edit/cust_pay.cgi +++ b/httemplate/edit/cust_pay.cgi @@ -46,6 +46,12 @@ Payment    <TD><INPUT TYPE="text" NAME="paid" VALUE="<% $paid %>" SIZE=8 MAXLENGTH=8> by <B><% FS::payby->payname($payby) %></B></TD>  </TR> +  <% include('/elements/tr-select-discount_term.html', +               'custnum' => $custnum, +               'cgi'     => $cgi +            ) +  %> +  % if ( $payby eq 'BILL' ) {     <TR>      <TD ALIGN="right">Check #</TD> diff --git a/httemplate/edit/part_pkg.cgi b/httemplate/edit/part_pkg.cgi index deefa9cc1..9144c4995 100755 --- a/httemplate/edit/part_pkg.cgi +++ b/httemplate/edit/part_pkg.cgi @@ -45,6 +45,7 @@                              'agentnum'         => 'Agent',                              'setup_fee'        => 'Setup fee',                              'recur_fee'        => 'Recurring fee', +                            'discountnum'      => 'Offer discounts for longer terms',                              'bill_dst_pkgpart' => 'Include line item(s) from package',                              'svc_dst_pkgpart'  => 'Include services of package',                              'report_option'    => 'Report classes', @@ -94,6 +95,7 @@                                  type  => 'selectlayers-select',                                  options => [ keys %plan_labels ],                                  labels  => \%plan_labels, +                                onchange => 'aux_planchanged(what);',                                },                                { field => 'setup_fee',                                  type  => 'money', @@ -195,6 +197,21 @@                                'multiple' => 1,                              }, +                            { 'type'    => 'tablebreak-tr-title', +                              'value'   => 'Term discounts', +                            }, +                            { 'field'      => 'discountnum', +                              'type'       => 'select-table', +                              'table'      => 'discount', +                              'name_col'   => 'name', +                              'hashref'    => { %$discountnum_hashref }, +                              #'extra_sql'  => 'AND (months IS NOT NULL OR months != 0)', +                              'empty_label'=> 'Select discount', +                              'm2_label'   => 'Offer discounts for longer terms', +                              'm2m_method' => 'part_pkg_discount', +                              'm2m_dstcol' => 'discountnum', +                              'm2_error_callback' => $discount_error_callback, +                            },                              { 'type'    => 'tablebreak-tr-title',                                'value'   => 'Pricing add-ons', @@ -426,6 +443,23 @@ my $clone_callback = sub {    $recur_disabled = $object->freq ? 0 : 1;  }; +my $discount_error_callback = sub { +  my( $cgi, $object ) = @_; +  map { +        if ( /^discountnum(\d+)$/ && +             ( my $discountnum = $cgi->param("discountnum$1") ) ) +        { +          new FS::part_pkg_discount { +            'pkgpart'     => $object->pkgpart, +            'discountnum' => $discountnum, +          }; +        } else { +          (); +        } +      } +  $cgi->param; +}; +  my $m2_error_callback_maker = sub {    my $link_type = shift; #yay closures    return sub { @@ -484,6 +518,22 @@ my $javascript = <<'END';      } +    function aux_planchanged(what) { + +      alert('called!'); +      var plan = what.options[what.selectedIndex].value; +      var table = document.getElementById('TableNumber7') // XXX NOT ROBUST + +      if ( plan == 'flat' || plan == 'prorate' || plan == 'subscription' ) { +        //table.disabled = false; +        table.style.visibility = ''; +      } else { +        //table.disabled = true; +        table.style.visibility = 'hidden'; +      } + +    } +    </SCRIPT>  END @@ -736,4 +786,9 @@ my $field_callback = sub {    }  }; +my $discountnum_hashref = { +                            'disabled' => '', +                            'months' => { 'op' => '>', 'value' => 1 }, +                          }; +  </%init> diff --git a/httemplate/edit/process/cust_pay.cgi b/httemplate/edit/process/cust_pay.cgi index df506c677..c8b0aa7df 100755 --- a/httemplate/edit/process/cust_pay.cgi +++ b/httemplate/edit/process/cust_pay.cgi @@ -47,7 +47,7 @@ my $new = new FS::cust_pay ( {    map {      $_, scalar($cgi->param($_));    } qw( paid payby payinfo paybatch -        pkgnum +        pkgnum discount_term        )    #} fields('cust_pay')  } ); diff --git a/httemplate/edit/process/part_pkg.cgi b/httemplate/edit/process/part_pkg.cgi index c0febf828..08cc14086 100755 --- a/httemplate/edit/process/part_pkg.cgi +++ b/httemplate/edit/process/part_pkg.cgi @@ -160,6 +160,12 @@ my @process_m2m = (      'target_table' => 'tax_class',      'params'       => \@tax_overrides,    }, +  { 'link_table'   => 'part_pkg_discount', +    'target_table' => 'discount', +    'params'       => [ map $cgi->param($_), +                        grep /^discountnum/, $cgi->param +                      ], +  },    { 'link_table'   => 'part_pkg_link',      'target_table' => 'part_pkg',      'base_field'   => 'src_pkgpart', diff --git a/httemplate/elements/customer-table.html b/httemplate/elements/customer-table.html index f00419f9c..3c3f8b2ee 100644 --- a/httemplate/elements/customer-table.html +++ b/httemplate/elements/customer-table.html @@ -22,6 +22,7 @@ Example:               ###               'name_singular' => 'customer', #label +             'custnum_update_callback' => 'name_of_js_callback' #passed a rownum               #listrefs               'types'         => ['immutable', ''], # immutable or ''/text @@ -98,6 +99,9 @@ Example:        if ( name.length > 0 ) {          customer.value = name;          customer.setAttribute('magic', 'nosearch'); +% if ( $opt{custnum_update_callback} ) { +        <% $opt{custnum_update_callback} %>(searchrow, '<% $opt{prefix} %>') +% }        } else {          customer.value = 'Not found';          customer.style.color = '#ff0000'; @@ -162,6 +166,9 @@ Example:          customer_obj.style.display = '';          customer_select.style.display = 'none'; +% if ( $opt{custnum_update_callback} ) { +        <% $opt{custnum_update_callback} %>(searchrow, '<% $opt{prefix} %>') +% }        } else { @@ -223,6 +230,10 @@ Example:        this.style.display = 'none';        customer_obj.style.display = ''; +% if ( $opt{custnum_update_callback} ) { +      <% $opt{custnum_update_callback} %>(searchrow, '<% $opt{prefix} %>') +% } +      }    } @@ -314,7 +325,7 @@ Example:          >  %     } elsif ($types->[$col] eq 'immutable') {          <% $font %><% $value %><% $font ? '</FONT>' : '' %> -        <INPUT TYPE="hidden" NAME="<% $name %>" VALUE="<% $value %>" > +        <INPUT TYPE="hidden" ID="<% $name %>" NAME="<% $name %>" VALUE="<% $value %>" >  %     } else {          Cannot represent unknown type: <% $types->[$col] %>  %     } diff --git a/httemplate/elements/select-discount_term.html b/httemplate/elements/select-discount_term.html new file mode 100644 index 000000000..26d877a86 --- /dev/null +++ b/httemplate/elements/select-discount_term.html @@ -0,0 +1,32 @@ +% if ( scalar(@discount_term) ) { +    <SELECT NAME="discount_term"> +      <OPTION VALUE="">1 month +%   foreach my $discount_term (@discount_term) { +%     my $sel = ( $cgi->param('discount_term') == $discount_term ) ? 'SELECTED' : ''; +      <OPTION <% $sel %> VALUE="<% $discount_term %>"><% $discount_term. " months" %> +%   } +    </SELECT> +% } +<%init> + +my %opt = @_; + +my $cgi = $opt{'cgi'}; + +my @discount_term; +if ( $opt{discount_term} ) { + +  @discount_term = @{ $opt{discount_term} }; + +} else { + +  my $custnum = $opt{'custnum'}; + +  my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } ) +    or die "unknown custnum $custnum\n"; + +  @discount_term = $cust_main->discount_terms; + +} + +</%init> diff --git a/httemplate/elements/tr-select-discount_term.html b/httemplate/elements/tr-select-discount_term.html new file mode 100644 index 000000000..58582675d --- /dev/null +++ b/httemplate/elements/tr-select-discount_term.html @@ -0,0 +1,25 @@ +% if ( scalar(@discount_term) ) { +  <TR> +    <TD ALIGN="right">Prepayment for</TD> +    <TD COLSPAN=2> +      <% include('select-discount_term.html', +                   'discount_term' => \@discount_term, +                   'cgi'           => $opt{'cgi'}, +                ) +      %> +    </TD> +  </TR> + +% } + +<%init> +my %opt = @_; + +my $custnum = $opt{'custnum'}; + +my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } ) +  or die "unknown custnum $custnum\n"; + +my @discount_term = $cust_main->discount_terms; + +</%init> diff --git a/httemplate/misc/batch-cust_pay.html b/httemplate/misc/batch-cust_pay.html index 505f2d0ff..610f6e1db 100644 --- a/httemplate/misc/batch-cust_pay.html +++ b/httemplate/misc/batch-cust_pay.html @@ -13,23 +13,63 @@ function warnUnload() {    }  }  window.onbeforeunload = warnUnload; + +function select_discount_term(row, prefix) { +  var custnum_obj = document.getElementById('custnum'+prefix+row); +  var select_obj = document.getElementById('discount_term'+prefix+row); + +  var value = ''; +  if (select_obj.type == 'hidden') { +    value = select_obj.value; +  } + +  var term_select = document.createElement('SELECT'); +  term_select.setAttribute('name', 'discount_term'+row); +  term_select.setAttribute('id',   'discount_term'+row); +  term_select.setAttribute('rownum', row); +  term_select.style.display = ''; +  select_obj.parentNode.replaceChild(term_select, select_obj); +  opt(term_select, '', '1 month'); +   +  function select_discount_term_update(discount_terms) { + +    var termArray = eval('(' + discount_terms + ')'); +    for ( var t = 0; t < termArray.length; t++ ) { +      opt(term_select, termArray[t][0], termArray[t][1]); +      if (termArray[t][0] == value) { +        term_select.selectedIndex = t+1; +      } +    } + +  } + +  discount_terms(custnum_obj.value, select_discount_term_update); + +}  </SCRIPT> +<% include('/elements/xmlhttp.html', +              'url'  => $p. 'misc/xmlhttp-cust_main-discount_terms.cgi', +              'subs' => [qw( discount_terms )], +           ) +%> +  <FORM ACTION="process/batch-cust_pay.cgi" NAME="OneTrueForm" METHOD="POST" onsubmit="document.OneTrueForm.submit.disabled=true;window.onbeforeunload = null;">  <!-- <B>Batch</B> <INPUT TYPE="text" NAME="paybatch"><BR><BR> -->  <% include( "/elements/customer-table.html",                name_singular => 'payment', -              header  => [ '', 'Amount', 'Check #', '' ], -              fields  => [ sub {'$'}, 'paid', 'payinfo', 'error', ], -              types   => [ 'immutable', '', '', 'immutable', ], -              align   => [ 'c', 'r', 'r', 'l' ], -              sizes   => [ 0, 8, 10, 0, ], -              colors  => [ '', '', '', '#ff0000' ], -              param   => { () }, -              footer  => [ '$', '_TOTAL', '', '' ], -              footer_align => [ 'c', 'r', 'r', '' ], +              header  => \@header, +              fields  => \@fields, +              types   => \@types, +              align   => \@align, +              sizes   => \@sizes, +              colors  => \@colors, +              param   => \%param, +              footer  => \@footer, +              footer_align => \@footer_align, +              custnum_update_callback => $custnum_update_callback,            )  %> @@ -41,6 +81,14 @@ window.onbeforeunload = warnUnload;  </FORM> +%if ( $cgi->param('error') ) { +<SCRIPT TYPE="text/javascript"> +%  for ( my $row = 0; defined($cgi->param("custnum$row")); $row++ ) { +     select_discount_term(<% $row %>, ''); +%  } +</SCRIPT> +%} +  <% include('/elements/footer.html') %>  <%init> @@ -48,4 +96,36 @@ window.onbeforeunload = warnUnload;  die "access denied"    unless $FS::CurrentUser::CurrentUser->access_right('Post payment batch'); +my @header  = ( '', 'Amount', 'Check #' ); +my @fields  = ( sub {'$'}, 'paid', 'payinfo' ); +my @types   = ( 'immutable', '', '' ); +my @align   = ( 'c', 'r', 'r' ); +my @sizes   = ( 0, 8, 10 ); +my @colors  = ( '', '', '' ); +my %param   = (); +my @footer  = ( '$', '_TOTAL', '' ); +my @footer_align = ( 'c', 'r', 'r' ); +my $custnum_update_callback = ''; + +if ( FS::Record->scalar_sql('SELECT count(*) FROM part_pkg_discount') ) { +  push @header, ''; +  push @fields, 'discount_term'; +  push @types, 'immutable'; +  push @align, 'r'; +  push @sizes, '0'; +  push @colors, ''; +  push @footer, ''; +  push @footer_align, ''; +  $custnum_update_callback = 'select_discount_term'; +} + +push @header, ''; +push @fields, 'error'; +push @types, 'immutable'; +push @align, 'l'; +push @sizes, '0'; +push @colors, '#ff0000'; +push @footer, ''; +push @footer_align, ''; +  </%init> diff --git a/httemplate/misc/payment.cgi b/httemplate/misc/payment.cgi index 813b560bd..bcab68aae 100644 --- a/httemplate/misc/payment.cgi +++ b/httemplate/misc/payment.cgi @@ -67,6 +67,11 @@  % } +<% include('/elements/tr-select-discount_term.html', +             'custnum' => $custnum, +             'cgi'     => $cgi +          ) +%>  % if ( $payby eq 'CARD' ) {  % diff --git a/httemplate/misc/process/batch-cust_pay.cgi b/httemplate/misc/process/batch-cust_pay.cgi index 4da00c63d..aefc00654 100644 --- a/httemplate/misc/process/batch-cust_pay.cgi +++ b/httemplate/misc/process/batch-cust_pay.cgi @@ -11,12 +11,13 @@  %  #while ( exists($param->{"custnum$row"}) ) {  %  for ( my $row = 0; exists($param->{"custnum$row"}); $row++ ) {  %    push @cust_pay, new FS::cust_pay { -%                                       'custnum'  => $param->{"custnum$row"}, -%                                       'paid'     => $param->{"paid$row"}, -%                                       'payby'    => 'BILL', -%                                       'payinfo'  => $param->{"payinfo$row"}, -%                                       'paybatch' => $paybatch, -%                                     } +%                      'custnum'        => $param->{"custnum$row"}, +%                      'paid'           => $param->{"paid$row"}, +%                      'payby'          => 'BILL', +%                      'payinfo'        => $param->{"payinfo$row"}, +%                      'discount_term'  => $param->{"discount_term$row"}, +%                      'paybatch'       => $paybatch, +%                    }  %      if    $param->{"custnum$row"}  %         || $param->{"paid$row"}  %         || $param->{"payinfo$row"}; diff --git a/httemplate/misc/process/payment.cgi b/httemplate/misc/process/payment.cgi index 665001ea9..c1c9071f9 100644 --- a/httemplate/misc/process/payment.cgi +++ b/httemplate/misc/process/payment.cgi @@ -119,19 +119,26 @@ if ( $payby eq 'CHEK' ) {    die "unknown payby $payby";  } +$cgi->param('discount_term') =~ /^\d*$/ +  or errorpage("illegal discount_term"); +my $discount_term = $1; +  my $error = '';  my $paynum = '';  if ( $cgi->param('batch') ) { -  $error = $cust_main->batch_card( -                                   'payby'    => $payby, -                                   'amount'   => $amount, -                                   'payinfo'  => $payinfo, -                                   'paydate'  => "$year-$month-01", -                                   'payname'  => $payname, -                                   map { $_ => $cgi->param($_) }  -                                     @{$payby2fields{$payby}} -                                 ); +  $error = 'Prepayment discounts not supported with batched payments'  +    if $discount_term; + +  $error ||= $cust_main->batch_card( +                                     'payby'    => $payby, +                                     'amount'   => $amount, +                                     'payinfo'  => $payinfo, +                                     'paydate'  => "$year-$month-01", +                                     'payname'  => $payname, +                                     map { $_ => $cgi->param($_) }  +                                       @{$payby2fields{$payby}} +                                   );    errorpage($error) if $error;  } else { @@ -146,6 +153,7 @@ if ( $cgi->param('batch') ) {      'payunique'  => $payunique,      'paycvv'     => $paycvv,      'paynum_ref' => \$paynum, +    'discount_term' => $discount_term,      map { $_ => $cgi->param($_) } @{$payby2fields{$payby}}    );    errorpage($error) if $error; diff --git a/httemplate/misc/xmlhttp-cust_main-discount_terms.cgi b/httemplate/misc/xmlhttp-cust_main-discount_terms.cgi new file mode 100644 index 000000000..71e2da597 --- /dev/null +++ b/httemplate/misc/xmlhttp-cust_main-discount_terms.cgi @@ -0,0 +1,24 @@ +% if ( $sub eq 'discount_terms' ) { +%  +%   my $return = []; +%   my $custnum = $cgi->param('arg'); +%   my $cust_main = ''; +%   $cust_main = qsearchs({ +%     'table'   => 'cust_main', +%     'hashref' => { 'custnum' => $custnum }, +%     'extra_sql' => ' AND '. $FS::CurrentUser::CurrentUser->agentnums_sql, +%   }); +%      +%   if ($cust_main) { +%     $return = [ map [ $_, "$_ months" ], $cust_main->discount_terms ]; +%   } +% +<% objToJson($return) %> +% }  +<%init> + +my $conf = new FS::Conf; + +my $sub = $cgi->param('sub'); + +</%init> diff --git a/httemplate/view/cust_main/packages/package.html b/httemplate/view/cust_main/packages/package.html index 3c486dd25..3b58f9ec0 100644 --- a/httemplate/view/cust_main/packages/package.html +++ b/httemplate/view/cust_main/packages/package.html @@ -39,6 +39,7 @@  %           if ( $curuser->access_right('Discount customer package')  %                && $part_pkg->can_discount  %                && ! scalar($cust_pkg->cust_pkg_discount_active) +%                && ! scalar($cust_pkg->part_pkg->part_pkg_discount)  %              )  %           {  %             $br=1; | 
