Package summary report, RT#8461
authormark <mark>
Thu, 5 Aug 2010 20:16:31 +0000 (20:16 +0000)
committermark <mark>
Thu, 5 Aug 2010 20:16:31 +0000 (20:16 +0000)
httemplate/elements/menu.html
httemplate/search/cust_pkg_summary.cgi [new file with mode: 0644]
httemplate/search/cust_pkg_summary.html [new file with mode: 0644]

index cd928e6..bc0c288 100644 (file)
@@ -179,6 +179,7 @@ if ( $curuser->access_right('Financial reports') ) {
   $report_packages{'separator2'} =  '';
 }
 $report_packages{'All customer packages'} =  [ $fsurl.'search/cust_pkg.cgi?pkgnum', 'List all customer packages', ];
+$report_packages{'Package summary'} = [ $fsurl.'search/cust_pkg_summary.html', 'Show package sales summary', ];
 $report_packages{'Suspended customer packages'} =  [ $fsurl.'search/cust_pkg.cgi?magic=suspended', 'List suspended packages' ];
 $report_packages{'Customer packages with unconfigured services'} =  [ $fsurl.'search/cust_pkg.cgi?APKG_pkgnum', 'List packages which have provisionable services' ];
 $report_packages{'FCC Form 477 packages'} =  [ $fsurl.'search/report_477.html', 'Summarize packages by census tract for particular types' ]
@@ -267,6 +268,7 @@ $report_menu{'Usage'} =  [ \%report_rating,    'Usage reports'  ]
 $report_menu{'Tickets'}   = [ \%report_ticketing, 'Ticket reports' ]
   if $conf->config('ticket_system')
   ;#&& FS::TicketSystem->access_right(\%session, 'Something');
+    'Package Costs Report' => [ $fsurl.'graph/report_cust_pkg_cost.html', 'Package setup and recurring costs graph' ],
 $report_menu{'Billing events'} =  [ \%report_bill_event, 'Billing events' ]
   if $curuser->access_right('Billing event reports');
 $report_menu{'Financial'}  = [ \%report_financial, 'Financial reports' ]
@@ -356,6 +358,8 @@ if ( $curuser->access_right('Configuration') ) {
 }
 
 tie my %config_agent, 'Tie::IxHash',
+$tools_menu{'Process invoice batches'} = [ $fsurl.'search/bill_batch.cgi' ] 
+  if ( $conf->exists('invoice_print_pdf') );
   'Agent types' => [ $fsurl.'browse/agent_type.cgi', 'Agent types define groups of package definitions that you can then assign to particular agents' ],
   'Agents'      => [ $fsurl.'browse/agent.cgi', 'Agents are resellers of your service. Agents may be limited to a subset of your full offerings (via their type)' ],
   'Agent payment gateways'         => [ $fsurl.'browse/payment_gateway.html', 'Credit card and electronic check processors for agent overrides' ];
diff --git a/httemplate/search/cust_pkg_summary.cgi b/httemplate/search/cust_pkg_summary.cgi
new file mode 100644 (file)
index 0000000..fc71c81
--- /dev/null
@@ -0,0 +1,87 @@
+<% include('/elements/header.html', $title) %>
+<% include('/elements/table-grid.html') %>
+  <TR>
+% foreach (@head) {
+    <TH CLASS="grid" BGCOLOR="#cccccc"><% $_ %></TH>
+% }
+  </TR>
+% my $r=0;
+% foreach my $row (@rows) {
+  <TR>
+%   foreach (@$row) {
+    <TD CLASS="grid" ALIGN="right" BGCOLOR="<% $r % 2 ? '#ffffff' : '#eeeeee' %>"><% $_ %></TD>
+%   }
+  </TR>
+%   $r++;
+% }
+  <TR>
+% foreach (@totals) {
+    <TD CLASS="grid" ALIGN="right" BGCOLOR="<% $r % 2 ? '#ffffff' : '#eeeeee' %>"><B><% $_ %></B></TD>
+% }
+  </TR>
+</TABLE>
+<%init>
+die "access denied"
+  unless $FS::CurrentUser::CurrentUser->access_right('List packages');
+
+my $title = 'Package Summary Report';
+my ($begin, $end) = FS::UI::Web::parse_beginning_ending($cgi);
+if($begin > 0) {
+  $title = "$title (".
+    $cgi->param('beginning').' - '.$cgi->param('ending').')';
+}
+
+my @h_sql = FS::h_cust_pkg->sql_h_search($end);
+
+my ($end_sql, $addl_from) = @h_sql[1,3];
+$end_sql =~ s/ORDER BY.*//; # breaks aggregate queries
+
+my $begin_sql = $end_sql;
+$begin_sql =~ s/$end/$begin/g;
+
+my $active_sql = FS::cust_pkg->active_sql;
+my $suspended_sql = FS::cust_pkg->suspended_sql;
+my @conds = (
+  # SQL WHERE clauses for each column of the table.
+  " $begin_sql AND ($active_sql OR $suspended_sql)",
+  '',
+  " $end_sql AND ($active_sql OR $suspended_sql)",
+  " $end_sql AND $active_sql",
+  " $end_sql AND $suspended_sql",
+  );
+
+$_ =~ s/\bcust_pkg/maintable/g foreach @conds;
+
+my @head = ('Package', 'Before Period', 'Sales', 'Total', 'Active', 'Suspended');
+my @rows = ();
+my @totals = ('Total', 0, 0, 0, 0, 0);
+
+if( !$begin ) {
+  splice @conds, 1, 1;
+  splice @head, 1, 1;
+}
+
+foreach my $part_pkg (qsearch('part_pkg', {} )) {
+  my @row = ();
+  next if !$part_pkg->freq; # exclude one-time packages
+  push @row, $part_pkg->pkg;
+  my $i=1;
+  foreach my $cond (@conds) {
+    if($cond) {
+      my $result = qsearchs({ 
+                            'table'     => 'h_cust_pkg',
+                            'hashref'   => {},
+                            'select'    => 'count(*)',
+                            'addl_from' => $addl_from,
+                            'extra_sql' => 'WHERE pkgpart = '.$part_pkg->pkgpart.$cond,
+                            });
+      $row[$i] = $result->getfield('count');
+      $totals[$i] += $row[$i];
+    }
+    $i++;
+  }
+  $row[2] = $row[3]-$row[1];
+  $totals[2] += $row[2];
+  push @rows, \@row;
+}
+</%init>
diff --git a/httemplate/search/cust_pkg_summary.html b/httemplate/search/cust_pkg_summary.html
new file mode 100644 (file)
index 0000000..a0ef472
--- /dev/null
@@ -0,0 +1,24 @@
+<% include( '/elements/header.html', 'Package Summary Report' ) %>
+
+<FORM ACTION="cust_pkg_summary.cgi" METHOD="GET">
+
+<TABLE BGCOLOR="#cccccc" CELLSPACING=0>
+
+  <TR>
+    <TH CLASS="background" COLSPAN=2 ALIGN="left">
+      <FONT SIZE="+1">Search options</FONT>
+    </TH>
+  </TR>
+
+  <% include ('/elements/tr-input-beginning_ending.html') %>
+
+</TABLE>
+
+<BR>
+<INPUT TYPE="submit" VALUE="Get Report">
+
+</FORM>
+
+<% include('/elements/footer.html') %>
+<%init>
+</%init>