diff options
| -rw-r--r-- | FS/FS.pm | 2 | ||||
| -rw-r--r-- | FS/FS/Mason.pm | 2 | ||||
| -rw-r--r-- | FS/FS/Report/Table/Monthly.pm | 47 | ||||
| -rw-r--r-- | FS/FS/Schema.pm | 14 | ||||
| -rw-r--r-- | FS/FS/cust_bill_pkg.pm | 15 | ||||
| -rw-r--r-- | FS/FS/cust_bill_pkg_discount.pm | 158 | ||||
| -rw-r--r-- | FS/FS/cust_main.pm | 4 | ||||
| -rw-r--r-- | FS/FS/cust_pkg.pm | 5 | ||||
| -rw-r--r-- | FS/FS/cust_pkg_discount.pm | 21 | ||||
| -rw-r--r-- | FS/FS/part_pkg/flat.pm | 11 | ||||
| -rw-r--r-- | FS/MANIFEST | 2 | ||||
| -rw-r--r-- | FS/t/cust_bill_pkg_discount.t | 5 | ||||
| -rw-r--r-- | httemplate/elements/menu.html | 9 | ||||
| -rw-r--r-- | httemplate/misc/delete-cust_pkg_discount.html | 4 | ||||
| -rw-r--r-- | httemplate/search/cust_bill_pkg_discount.html | 151 | ||||
| -rw-r--r-- | httemplate/search/cust_pkg_discount.html | 122 | ||||
| -rw-r--r-- | httemplate/search/report_cust_bill_pkg_discount.html | 47 | ||||
| -rw-r--r-- | httemplate/search/report_cust_pkg_discount.html | 50 | 
18 files changed, 660 insertions, 9 deletions
| @@ -228,6 +228,8 @@ L<FS::cust_pkg_detail> - Customer package details class  L<FS:;cust_pkg_discount> - Customer package discount class +L<FS:;cust_bill_pkg_discount> - Customer package discount line item application class +  L<FS:;discount> - Discount class  L<FS::reason_type> - Reason type class diff --git a/FS/FS/Mason.pm b/FS/FS/Mason.pm index d812e8184..f20ea647a 100644 --- a/FS/FS/Mason.pm +++ b/FS/FS/Mason.pm @@ -228,6 +228,8 @@ if ( -e $addl_handler_use_file ) {    use FS::contact;    use FS::svc_pbx;    use FS::discount; +  use FS::cust_pkg_discount; +  use FS::cust_bill_pkg_discount;    # Sammath Naur    if ( $FS::Mason::addl_handler_use ) { diff --git a/FS/FS/Report/Table/Monthly.pm b/FS/FS/Report/Table/Monthly.pm index fa9949d49..9e7a2882f 100644 --- a/FS/FS/Report/Table/Monthly.pm +++ b/FS/FS/Report/Table/Monthly.pm @@ -417,6 +417,53 @@ sub cust_bill_pkg_detail {  } +sub cust_bill_pkg_discount { +  my( $self, $speriod, $eperiod, $agentnum, %opt ) = @_; + +  #my $where = ''; +  #my $comparison = ''; +  #if ( $opt{'classnum'} =~ /^(\d+)$/ ) { +  #  if ( $1 == 0 ) { +  #    $comparison = "IS NULL"; +  #  } else { +  #    $comparison = "= $1"; +  #  } +  # +  #  if ( $opt{'use_override'} ) { +  #    $where = "( +  #      part_pkg.classnum $comparison AND pkgpart_override IS NULL OR +  #      override.classnum $comparison AND pkgpart_override IS NOT NULL +  #    )"; +  #  } else { +  #    $where = "part_pkg.classnum $comparison"; +  #  } +  #} + +  $agentnum ||= $opt{'agentnum'}; + +  my $total_sql = +    " SELECT COALESCE( SUM( cust_bill_pkg_discount.amount ), 0 ) "; + +  #$total_sql .= +  #  " / CASE COUNT(cust_pkg.*) WHEN 0 THEN 1 ELSE COUNT(cust_pkg.*) END " +  #    if $opt{average_per_cust_pkg}; + +  $total_sql .= +    " FROM cust_bill_pkg_discount +        LEFT JOIN cust_bill_pkg USING ( billpkgnum ) +        LEFT JOIN cust_bill USING ( invnum ) +        LEFT JOIN cust_main USING ( custnum ) +      WHERE ". $self->in_time_period_and_agent($speriod, $eperiod, $agentnum); +  #      LEFT JOIN cust_pkg_discount USING ( pkgdiscountnum ) +  #      LEFT JOIN discount USING ( discountnum ) +  #      LEFT JOIN cust_pkg USING ( pkgnum ) +  #      LEFT JOIN part_pkg USING ( pkgpart ) +  #      LEFT JOIN part_pkg AS override ON pkgpart_override = override.pkgpart +   +  return $self->scalar_sql($total_sql); + +} +  sub setup_pkg  { shift->pkg_field( @_, 'setup' ); }  sub susp_pkg   { shift->pkg_field( @_, 'susp'  ); }  sub cancel_pkg { shift->pkg_field( @_, 'cancel'); } diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index ad094d7c1..19c2e8e58 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -1317,12 +1317,26 @@ sub tables_hashref {          'months_used',   'decimal', 'NULL', '', '', '',          'end_date',     @date_type,             '', '',          'otaker',        'varchar', '',     32, '', '',  +        'disabled',         'char', 'NULL',  1, '', '',         ],        'primary_key' => 'pkgdiscountnum',        'unique' => [],        'index'  => [ [ 'pkgnum' ], [ 'discountnum' ] ],      }, +    'cust_bill_pkg_discount' => { +      'columns' => [ +        'billpkgdiscountnum', 'serial',     '', '', '', '', +        'billpkgnum',            'int',     '', '', '', '',  +        'pkgdiscountnum',        'int',     '', '', '', '',  +        'amount',          @money_type,             '', '',  +        'months',            'decimal', 'NULL', '', '', '', +      ], +      'primary_key' => 'billpkgdiscountnum', +      'unique' => [], +      'index' => [ [ 'billpkgnum' ], [ 'pkgdiscountnum' ] ], +    }, +      'discount' => {        'columns' => [          'discountnum', 'serial',     '',      '', '', '', diff --git a/FS/FS/cust_bill_pkg.pm b/FS/FS/cust_bill_pkg.pm index cd049d121..cb070d77a 100644 --- a/FS/FS/cust_bill_pkg.pm +++ b/FS/FS/cust_bill_pkg.pm @@ -174,6 +174,17 @@ sub insert {      }    } +  if ( $self->get('discounts') ) { +    foreach my $cust_bill_pkg_discount ( @{$self->get('discounts')} ) { +      $cust_bill_pkg_discount->billpkgnum($self->billpkgnum); +      $error = $cust_bill_pkg_discount->insert; +      if ( $error ) { +        $dbh->rollback if $oldAutoCommit; +        return "error inserting cust_bill_pkg_discount: $error"; +      } +    } +  } +    if ( $self->_cust_tax_exempt_pkg ) {      foreach my $cust_tax_exempt_pkg ( @{$self->_cust_tax_exempt_pkg} ) {        $cust_tax_exempt_pkg->billpkgnum($self->billpkgnum); @@ -763,10 +774,10 @@ sub cust_bill_pkg_display {    my $type = $opt{type} if exists $opt{type};    my @result; -  if ( scalar( $self->get('display') ) ) { +  if ( $self->get('display') ) {      @result = grep { defined($type) ? ($type eq $_->type) : 1 }                @{ $self->get('display') }; -  }else{ +  } else {      my $hashref = { 'billpkgnum' => $self->billpkgnum };      $hashref->{type} = $type if defined($type); diff --git a/FS/FS/cust_bill_pkg_discount.pm b/FS/FS/cust_bill_pkg_discount.pm new file mode 100644 index 000000000..e7dd5f22f --- /dev/null +++ b/FS/FS/cust_bill_pkg_discount.pm @@ -0,0 +1,158 @@ +package FS::cust_bill_pkg_discount; + +use strict; +use base qw( FS::cust_main_Mixin FS::Record ); +use FS::Record qw( qsearch qsearchs ); +use FS::cust_bill_pkg; +use FS::cust_pkg_discount; + +=head1 NAME + +FS::cust_bill_pkg_discount - Object methods for cust_bill_pkg_discount records + +=head1 SYNOPSIS + +  use FS::cust_bill_pkg_discount; + +  $record = new FS::cust_bill_pkg_discount \%hash; +  $record = new FS::cust_bill_pkg_discount { 'column' => 'value' }; + +  $error = $record->insert; + +  $error = $new_record->replace($old_record); + +  $error = $record->delete; + +  $error = $record->check; + +=head1 DESCRIPTION + +An FS::cust_bill_pkg_discount object represents the slice of a customer +applied to a line item.  FS::cust_bill_pkg_discount inherits from +FS::Record.  The following fields are currently supported: + +=over 4 + +=item billpkgdiscountnum + +primary key + +=item billpkgnum + +Line item (see L<FS::cust_bill_pkg>) + +=item pkgdiscountnum + +Customer discount (see L<FS::cust_pkg_discount>) + +=item amount + +Amount discounted from the line itme. + +=item months + +Number of months of discount this represents. + +=back + +=head1 METHODS + +=over 4 + +=item new HASHREF + +Creates a new record.  To add the record to the database, see L<"insert">. + +Note that this stores the hash reference, not a distinct copy of the hash it +points to.  You can ask the object for a copy with the I<hash> method. + +=cut + +# the new method can be inherited from FS::Record, if a table method is defined + +sub table { 'cust_bill_pkg_discount'; } + +=item insert + +Adds this record to the database.  If there is an error, returns the error, +otherwise returns false. + +=cut + +# the insert method can be inherited from FS::Record + +=item delete + +Delete this record from the database. + +=cut + +# the delete method can be inherited from FS::Record + +=item replace OLD_RECORD + +Replaces the OLD_RECORD with this one in the database.  If there is an error, +returns the error, otherwise returns false. + +=cut + +# the replace method can be inherited from FS::Record + +=item check + +Checks all fields to make sure this is a valid record.  If there is +an error, returns the error, otherwise returns false.  Called by the insert +and replace methods. + +=cut + +sub check { +  my $self = shift; + +  my $error =  +    $self->ut_numbern('billpkgdiscountnum') +    || $self->ut_foreign_key('billpkgnum', 'cust_bill_pkg', 'billpkgnum' ) +    || $self->ut_foreign_key('pkgdiscountnum', 'cust_pkg_discount', 'pkgdiscountnum' ) +    || $self->ut_money('amount') +    || $self->ut_float('months') +  ; +  return $error if $error; + +  $self->SUPER::check; +} + +=item cust_bill_pkg + +Returns the associated line item (see L<FS::cust_bill_pkg>). + +=cut + +sub cust_bill_pkg { +  my $self = shift; +  qsearchs( 'cust_bill_pkg', { 'billpkgnum' => $self->billpkgnum } ) ; +} + +=item cust_pkg_discount + +Returns the associated customer discount (see L<FS::cust_pkg_discount>). + +=cut + +sub cust_pkg_discount { +  my $self = shift; +  qsearchs( 'cust_pkg_discount', { 'pkgdiscountnum' => $self->pkgdiscountnum }); +} + + +=back + +=head1 BUGS + +=head1 SEE ALSO + +L<FS::Record>, schema.html from the base documentation. + +=cut + +1; + diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm index 590e32ff2..d4ce0fd67 100644 --- a/FS/FS/cust_main.pm +++ b/FS/FS/cust_main.pm @@ -3065,7 +3065,7 @@ sub _make_lines {    my $old_cust_pkg = new FS::cust_pkg \%hash;    my @details = (); - +  my @discounts = ();    my $lineitems = 0;    $cust_pkg->pkgpart($part_pkg->pkgpart); @@ -3150,6 +3150,7 @@ sub _make_lines {                                );      my %param = ( 'precommit_hooks'     => $precommit_hooks,                    'increment_next_bill' => $increment_next_bill, +                  'discounts'           => \@discounts,                  );      my $method = $options{cancel} ? 'calc_cancel' : 'calc_recur'; @@ -3229,6 +3230,7 @@ sub _make_lines {          'unitrecur' => $unitrecur,          'quantity'  => $cust_pkg->quantity,          'details'   => \@details, +        'discounts' => \@discounts,          'hidden'    => $part_pkg->hidden,        }; diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm index acc73dfda..c3734b54e 100644 --- a/FS/FS/cust_pkg.pm +++ b/FS/FS/cust_pkg.pm @@ -2388,10 +2388,7 @@ sub cust_pkg_discount {  sub cust_pkg_discount_active {    my $self = shift; -  grep { my $d = $_->discount; -         ! $d->months || $_->months_used < $d->months; # XXX also end date -       } -       $self->cust_pkg_discount; +  grep { $_->status eq 'active' } $self->cust_pkg_discount;  }  =back diff --git a/FS/FS/cust_pkg_discount.pm b/FS/FS/cust_pkg_discount.pm index 8dd00de89..1b97bba03 100644 --- a/FS/FS/cust_pkg_discount.pm +++ b/FS/FS/cust_pkg_discount.pm @@ -1,7 +1,7 @@  package FS::cust_pkg_discount;  use strict; -use base qw( FS::Record ); +use base qw( FS::cust_main_Mixin FS::Record );  use FS::Record qw( dbh qsearchs ); # qsearch );  use FS::cust_pkg;  use FS::discount; @@ -165,6 +165,7 @@ sub check {      || $self->ut_float('months_used') #actually decimal, but this will do      || $self->ut_numbern('end_date')      || $self->ut_text('otaker') +    || $self->ut_enum('disabled', [ '', 'Y' ] )    ;    return $error if $error; @@ -207,6 +208,24 @@ sub increment_months_used {    $self->replace();  } +=item status + +=cut + +sub status { +  my $self = shift; +  my $discount = $self->discount; + +  if ( $self->disabled ne 'Y'  +       and ( ! $discount->months || $self->months_used < $discount->months ) +             #XXX also end date +     ) { +    'active'; +  } else { +    'expired'; +  } +} +  =back  =head1 BUGS diff --git a/FS/FS/part_pkg/flat.pm b/FS/FS/part_pkg/flat.pm index e5fc089c4..b825dded6 100644 --- a/FS/FS/part_pkg/flat.pm +++ b/FS/FS/part_pkg/flat.pm @@ -11,6 +11,7 @@ use List::Util qw(min); # max);  use FS::UI::bytecount;  use FS::Conf;  use FS::part_pkg; +use FS::cust_bill_pkg_discount;  @ISA = qw(FS::part_pkg); @@ -190,6 +191,16 @@ sub calc_discount {       $amount *= $months;       $amount = sprintf('%.2f', $amount); +     next unless $amount > 0; + +     #record details in cust_bill_pkg_discount +     my $cust_bill_pkg_discount = new FS::cust_bill_pkg_discount { +       'pkgdiscountnum' => $cust_pkg_discount->pkgdiscountnum, +       'amount'         => $amount, +       'months'         => $months, +     }; +     push @{ $param->{'discounts'} }, $cust_bill_pkg_discount; +       #add details on discount to invoice       my $conf = new FS::Conf;       my $money_char = $conf->config('money_char') || '$';   diff --git a/FS/MANIFEST b/FS/MANIFEST index a92b9ddd7..71523458a 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -480,3 +480,5 @@ FS/discount.pm  t/discount.t  FS/cust_pkg_discount.pm  t/cust_pkg_discount.t +FS/cust_bill_pkg_discount.pm +t/cust_bill_pkg_discount.t diff --git a/FS/t/cust_bill_pkg_discount.t b/FS/t/cust_bill_pkg_discount.t new file mode 100644 index 000000000..74923e1b0 --- /dev/null +++ b/FS/t/cust_bill_pkg_discount.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::cust_bill_pkg_discount; +$loaded=1; +print "ok 1\n"; diff --git a/httemplate/elements/menu.html b/httemplate/elements/menu.html index 5090abc73..1694a5927 100644 --- a/httemplate/elements/menu.html +++ b/httemplate/elements/menu.html @@ -102,6 +102,13 @@ tie my %report_invoices, 'Tie::IxHash',    'Advanced invoice reports' => [ $fsurl.'search/report_cust_bill.html', 'by agent, date range, etc.' ],  ; +tie my %report_discounts, 'Tie::IxHash', +  'Discount graph'  => [ $fsurl. 'graph/report_cust_bill_pkg_discount.html', 'Discount overview per month' ], +  'Discount detail' => [ $fsurl.'search/report_cust_bill_pkg_discount.html', 'Discount report (by employee and/or date range)' ], +  #awful name +  'Package discounts' => [ $fsurl.'search/report_cust_pkg_discount.html', 'Active/inactive discounts by package' ], +; +  tie my %report_services, 'Tie::IxHash';  if ( $curuser->access_right('Configuration') ) {    $report_services{'Service definitions'} =  [ $fsurl.'browse/part_svc.cgi?orderby=active', 'Service definitions by number of active packages' ]; @@ -262,6 +269,8 @@ $report_menu{'Customers'}   = [ \%report_customers, 'Customer reports'  ]    if $curuser->access_right('List customers');  $report_menu{'Invoices'}    =  [ \%report_invoices,  'Invoice reports'   ]    if $curuser->access_right('List invoices'); +$report_menu{'Discounts'}   =  [ \%report_discounts, 'Discount reports'  ] +  if $curuser->access_right('Financial reports');  $report_menu{'Payments'}    =  [ \%report_payments,  'Payment reports'   ]    if $curuser->access_right('Financial reports');  $report_menu{'Packages'}    =  [ \%report_packages,  'Package reports'   ] diff --git a/httemplate/misc/delete-cust_pkg_discount.html b/httemplate/misc/delete-cust_pkg_discount.html index 69168af3b..0bdaa13b3 100644 --- a/httemplate/misc/delete-cust_pkg_discount.html +++ b/httemplate/misc/delete-cust_pkg_discount.html @@ -25,6 +25,8 @@ my $cust_pkg_discount =  my $cust_pkg = $cust_pkg_discount->cust_pkg;  my $custnum = $cust_pkg->custnum; -my $error = $cust_pkg_discount->delete; +$cust_pkg_discount->disabled('Y'); + +my $error = $cust_pkg_discount->replace;  </%init> diff --git a/httemplate/search/cust_bill_pkg_discount.html b/httemplate/search/cust_bill_pkg_discount.html new file mode 100644 index 000000000..088b29115 --- /dev/null +++ b/httemplate/search/cust_bill_pkg_discount.html @@ -0,0 +1,151 @@ +<% include( 'elements/search.html', +                 'title'       => 'Discounts', +                 'name'        => 'discounts', +                 'query'       => $query, +                 'count_query' => $count_query, +                 'count_addl'  => [ $money_char. '%.2f total', ], +                 'header'      => [ +                   #'#', +                   'Discount', +                   'Amount', +                   'Months', +                   'Package', +                   'Invoice', +                   'Date', +                   FS::UI::Web::cust_header(), +                 ], +                 'fields'      => [ +                   #'billpkgdiscountnum', +                   sub { $_[0]->cust_pkg_discount->discount->description }, +                   sub { sprintf($money_char.'%.2f', shift->amount ) }, +                   sub { my $m = shift->months; +                         $m =~ /\./ ? sprintf('%.2f', $m) : $m; +                       }, +                   'pkg',#sub { $_[0]->cust_bill_pkg->cust_pkg->part_pkg->pkg }, +                   'invnum', +                   sub { time2str('%b %d %Y', shift->_date ) }, +                   \&FS::UI::Web::cust_fields, +                 ], +                 'links'       => [ +                   #'', +                   '', #link to customer discount??? +                   '', +                   '', +                   '', +                   $ilink, +                   $ilink, +                   ( map { $_ ne 'Cust. Status' ? $clink : '' } +                         FS::UI::Web::cust_header() +                   ), +                 ], +                 #'align' => 'rlrrrc'.FS::UI::Web::cust_aligns(), +                 'align' => 'lrrlrr'.FS::UI::Web::cust_aligns(), +                 'color' => [  +                              #'', +                              '', +                              '', +                              '', +                              '', +                              '', +                              '', +                              FS::UI::Web::cust_colors(), +                            ], +                 'style' => [  +                              #'', +                              '', +                              '', +                              '', +                              '', +                              '', +                              '', +                              FS::UI::Web::cust_styles(), +                            ], +           ) +%> +<%init> + +#a little false laziness below w/cust_bill_pkg.cgi + +die "access denied" +  unless $FS::CurrentUser::CurrentUser->access_right('Financial reports'); + +my $conf = new FS::Conf; + +#here is the agent virtualization +my $agentnums_sql = +  $FS::CurrentUser::CurrentUser->agentnums_sql( 'table' => 'cust_main' ); + +my @where = ( $agentnums_sql ); + +my($beginning, $ending) = FS::UI::Web::parse_beginning_ending($cgi); +push @where, "_date >= $beginning", +             "_date <= $ending"; + +if ( $cgi->param('agentnum') =~ /^(\d+)$/ ) { +  push @where, "cust_main.agentnum = $1"; +} + +# #classnum +# # not specified: all classes +# # 0: empty class +# # N: classnum +# my $use_override = $cgi->param('use_override'); +# if ( $cgi->param('classnum') =~ /^(\d+)$/ ) { +#   my $comparison = ''; +#   if ( $1 == 0 ) { +#     $comparison = "IS NULL"; +#   } else { +#     $comparison = "= $1"; +#   } +#  +#   if ( $use_override ) { +#     push @where, "( +#       part_pkg.classnum $comparison AND pkgpart_override IS NULL OR +#       override.classnum $comparison AND pkgpart_override IS NOT NULL +#     )"; +#   } else { +#     push @where, "part_pkg.classnum $comparison"; +#   } +# } + +my $count_query = "SELECT COUNT(*), SUM(amount)"; + +my $join_cust =  '      JOIN cust_bill_pkg USING ( billpkgnum ) +                        JOIN cust_bill USING ( invnum )  +                   LEFT JOIN cust_main USING ( custnum ) '; + +my $join_pkg = ' LEFT JOIN cust_pkg USING ( pkgnum ) +                 LEFT JOIN part_pkg USING ( pkgpart ) '; +                 #LEFT JOIN part_pkg AS override +                 #  ON pkgpart_override = override.pkgpart '; + +my $where = ' WHERE '. join(' AND ', @where); + +$count_query .= " FROM cust_bill_pkg_discount $join_cust $join_pkg $where"; + +my @select = ( +               'cust_bill_pkg_discount.*', +               #'cust_bill_pkg.*', +               'cust_bill.invnum', +               'cust_bill._date', +             ); +push @select, 'part_pkg.pkg'; +push @select, 'cust_main.custnum', +              FS::UI::Web::cust_sql_fields(); + +my $query = { +  'table'     => 'cust_bill_pkg_discount', +  'addl_from' => "$join_cust $join_pkg", +  'hashref'   => {}, +  'select'    => join(', ', @select ), +  'extra_sql' => $where, +  'order_by'  => 'ORDER BY _date, billpkgdiscountnum', +}; + +my $ilink = [ "${p}view/cust_bill.cgi?", 'invnum' ]; +my $clink = [ "${p}view/cust_main.cgi?", 'custnum' ]; + +my $conf = new FS::Conf; +my $money_char = $conf->config('money_char') || '$'; + +</%init> diff --git a/httemplate/search/cust_pkg_discount.html b/httemplate/search/cust_pkg_discount.html new file mode 100644 index 000000000..233345e1c --- /dev/null +++ b/httemplate/search/cust_pkg_discount.html @@ -0,0 +1,122 @@ +<% include( 'elements/search.html', +                  'title'       => 'Package discounts',  +                  'name'        => 'discounts', +                  'query'       => $query, +                  'count_query' => $count_query, +                  #'redirect'    => $link, +                  'header'      => [ 'Status', +                                     'Discount', +                                     'Months used', +                                     'Employee', +                                     'Package', +                                     FS::UI::Web::cust_header( +                                     #  $cgi->param('cust_fields') +                                     ), +                                   ], +                  'fields'      => [ +                                     sub { ucfirst( shift->status ) }, +                                     sub { shift->discount->description }, +                                     sub { my $m = shift->months_used; +                                           $m =~ /\./ ? sprintf('%.2f',$m) : $m; +                                         }, +                                     'otaker', +                                     'pkg', +                                     \&FS::UI::Web::cust_fields, +                                   ], +                  'links'       => [ +                                     '', +                                     '', +                                     '', +                                     '', +                                     '', +                                     ( map { $_ ne 'Cust. Status' ? $clink : ''} +                                           FS::UI::Web::cust_header() +                                     ), +                                   ], +                  'align'       => 'clrll'. FS::UI::Web::cust_aligns(), +                  'color'       => [  +                                     '', +                                     '', +                                     '', +                                     '', +                                     '', +                                     FS::UI::Web::cust_colors(), +                                   ], +                 'style'        => [  +                                     '', +                                     '', +                                     '', +                                     '', +                                     '', +                                     FS::UI::Web::cust_styles(), +                                   ], +           ) +%> +<%init> + +die "access denied" +  unless $FS::CurrentUser::CurrentUser->access_right('Financial reports'); + +#my $conf = new FS::Conf; + +#here is the agent virtualization +my $agentnums_sql = +  $FS::CurrentUser::CurrentUser->agentnums_sql( 'table' => 'cust_main' ); + +my @where = ( $agentnums_sql ); + +#status +if ( $cgi->param('status') eq 'active' ) { +  push @where, "     (    cust_pkg_discount.disabled IS NULL +                       OR cust_pkg_discount.disabled != 'Y'  ) +                 AND ( months IS NULL OR months_used < months ) "; +                       #XXX also end date +} elsif ( $cgi->param('status') eq 'expired' ) { +  push @where, "    (      cust_pkg_discount.disabled IS NOT NULL +                      AND  cust_pkg_discount.disabled = 'Y'       ) +                 OR ( months IS NOT NULL AND months_used >= months ) +               ";     #XXX also end date +} + +#otaker +if ( $cgi->param('otaker') && $cgi->param('otaker') =~ /^([\w\.\-]+)$/ ) { +  push @where, "cust_pkg_discount.otaker = '$1'"; +} + +#agent +if ( $cgi->param('agentnum') =~ /^(\d+)$/ ) { +  push @where, "cust_main.agentnum = $1"; +} + +my $count_query = "SELECT COUNT(*), SUM(amount)"; + +my $join = ' LEFT JOIN discount  USING ( discountnum ) +             LEFT JOIN cust_pkg  USING ( pkgnum ) +             LEFT JOIN part_pkg  USING ( pkgpart ) +             LEFT JOIN cust_main USING ( custnum ) '; + +my $where = ' WHERE '. join(' AND ', @where); + +$count_query .= " FROM cust_pkg_discount $join $where"; + +my @select = ( +               'cust_pkg_discount.*', +               'part_pkg.pkg', +             ); +push @select, 'cust_main.custnum', +              FS::UI::Web::cust_sql_fields(); + +my $query = { +  'table'     => 'cust_pkg_discount', +  'addl_from' => $join, +  'hashref'   => {}, +  'select'    => join(', ', @select ), +  'extra_sql' => $where, +  'order_by'  => 'ORDER BY pkgdiscountnum', +}; + +my $clink = [ "${p}view/cust_main.cgi?", 'custnum' ]; + +my $conf = new FS::Conf; + +</%init> diff --git a/httemplate/search/report_cust_bill_pkg_discount.html b/httemplate/search/report_cust_bill_pkg_discount.html new file mode 100644 index 000000000..f1879d4a9 --- /dev/null +++ b/httemplate/search/report_cust_bill_pkg_discount.html @@ -0,0 +1,47 @@ +<% include('/elements/header.html', 'Discount report' ) %> + +<FORM ACTION="cust_bill_pkg_discount.html" METHOD="GET"> + + +<TABLE> + +  <% include( '/elements/tr-select-otaker.html', +                'label'   => 'Discounts by employee: ', +                'otakers' => \@otakers, +            ) +  %> + +  <% include( '/elements/tr-select-agent.html', +                 'curr_value'    => scalar( $cgi->param('agentnum') ), +                 'label'         => 'for agent: ', +                 'disable_empty' => 0, +             ) +  %> + +  <% include( '/elements/tr-input-beginning_ending.html' ) %> + +  <% include( '/elements/tr-input-lessthan_greaterthan.html', +                'label' => 'Amount', +		'field' => 'amount', +            ) +  %> + +</TABLE> + +<BR> +<INPUT TYPE="submit" VALUE="Get Report"> + +</FORM> + +<% include('/elements/footer.html') %> +<%init> + +die "access denied" +  unless $FS::CurrentUser::CurrentUser->access_right('Financial reports'); + +my $sth = dbh->prepare("SELECT DISTINCT otaker FROM cust_pkg_discount") +  or die dbh->errstr; +$sth->execute or die $sth->errstr; +my @otakers = map { $_->[0] } @{$sth->fetchall_arrayref}; + +</%init> diff --git a/httemplate/search/report_cust_pkg_discount.html b/httemplate/search/report_cust_pkg_discount.html new file mode 100644 index 000000000..7ebd44f75 --- /dev/null +++ b/httemplate/search/report_cust_pkg_discount.html @@ -0,0 +1,50 @@ +<% include('/elements/header.html', 'Package discount report' ) %> + +<FORM ACTION="cust_pkg_discount.html" METHOD="GET"> + + +<TABLE> + +  <TR> +    <TD>Discount status</TD> +    <TD> +      <SELECT NAME="status"> +        <OPTION VALUE="active">Active +        <OPTION VALUE="expired">Expired +        <OPTION VALUE="">(all) +      </SELECT> +    </TD> +  </TR> + +  <% include( '/elements/tr-select-otaker.html', +                'label'   => 'Discounts by employee: ', +                'otakers' => \@otakers, +            ) +  %> + +  <% include( '/elements/tr-select-agent.html', +                 'curr_value'    => scalar( $cgi->param('agentnum') ), +                 'label'         => 'for agent: ', +                 'disable_empty' => 0, +             ) +  %> + +</TABLE> + +<BR> +<INPUT TYPE="submit" VALUE="Get Report"> + +</FORM> + +<% include('/elements/footer.html') %> +<%init> + +die "access denied" +  unless $FS::CurrentUser::CurrentUser->access_right('Financial reports'); + +my $sth = dbh->prepare("SELECT DISTINCT otaker FROM cust_pkg_discount") +  or die dbh->errstr; +$sth->execute or die $sth->errstr; +my @otakers = map { $_->[0] } @{$sth->fetchall_arrayref}; + +</%init> | 
