deposit slips
[freeside.git] / httemplate / search / e911.html
1 <%doc>
2
3   E911 Fee Report
4
5   Finds billing totals for a given pkgpart where the bill item matches
6   cust_pkg.pkgpart or cust_bill_pkg.pkgpart_override columns.
7
8   Given date range, filter by when the invoice was paid.
9
10   * E911 access lines - SUM(cust_bill_pkg.quantity)
11   * Total fees charged - SUM(cust_bill_pay_pkg.amount)
12   * Fee payments collected - SUM(cust_bill_pkg.setup) + SUM(cust_bill_pkg.recur)
13
14   * Administrative fee (1%) - 1% of Fee Payments Collected
15   * Amount due - 99% of Fee Payments Collected
16
17 </%doc>
18 % if ( $row ) {
19 <& /elements/header.html, 'E911 Fee Report' &>
20
21 <& /elements/table-grid.html &>
22 <STYLE TYPE="text/css">
23 table.grid TD:first-child { font-weight: normal }
24 table.grid TD { font-weight: bold;
25                 text-align: right;
26                 padding: 1px 2px }
27 </STYLE>
28
29   <TR><TH COLSPAN=2><% $legend %></TH></TR>
30   <TR>
31     <TD><% mt('E911 access lines') %>:</TD>
32     <TD><% $report{e911_access_lines} %></TD>
33   </TR>
34   <TR>
35     <TD><% mt('Total fees charged') %>: </TD>
36     <TD><% $money_char.$report{fees_charged} %></TD>
37   </TD>
38   <TR>
39     <TD><% mt('Fee payments collected') %>: </TD>
40     <TD><% $money_char.$report{fees_collected} %></TD>
41   </TR>
42   <TR>
43     <TD><% mt('Administrative fee') %> (1%): </TD>
44     <TD><% $money_char.$report{admin_fee} %></TD>
45   </TR>
46   <TR>
47     <TD><% mt('Amount due') %>: </TD>
48     <TD><% $money_char.$report{e911_amount_due} %></TD>
49   </TR>
50 </TABLE>
51 <& /elements/footer.html &>
52 % } else { # no data
53 %   $cgi->param('error' => 'No paid E911 fees found.');
54 <& /elements/errorpage.html &>
55 % }
56 <%init>
57
58 our $DEBUG;
59
60 die "access denied"
61   unless $FS::CurrentUser::CurrentUser->access_right('Financial reports');
62
63 my $money_char = FS::Conf->new->config('money_char') || '$';
64
65 my($begin, $end) = FS::UI::Web::parse_beginning_ending($cgi);
66
67 $cgi->param('e911pkgpart') =~ /^(\d+)$/;
68 my $pkgpart = $1 or die 'bad e911pkgpart';
69
70 $cgi->param('agentnum') =~ /^(\d*)$/;
71 my $agentnum = $1;
72
73 # This has the potential to become as nightmarish as the old tax report.
74 # If we end up doing multiple rows for some reason (date intervals, 
75 # package classes, etc.), do NOT simply loop through this and do a 
76 # bazillion scalar_sql queries.  Use a properly grouped aggregate query.
77
78 my $sql_statement = "
79   SELECT
80     sum(cust_bill_pkg.quantity) as quantity,
81     sum(cust_bill_pay_pkg.amount) as amount,
82     sum(cust_bill_pkg.setup) as setup,
83     sum(cust_bill_pkg.recur) as recur
84
85   FROM cust_pkg
86     LEFT JOIN cust_bill_pkg      USING (pkgnum)
87     LEFT JOIN cust_bill_pay_pkg  USING (billpkgnum)
88     LEFT JOIN cust_bill_pay      USING (billpaynum)
89 ";
90 if ( $agentnum ) {
91   $sql_statement .= "
92       LEFT JOIN cust_main          USING (custnum)
93     WHERE
94       cust_main.agentnum = ?
95       AND ";
96 } else {
97   $sql_statement .= "
98     WHERE
99   "
100 }
101 $sql_statement .= "
102     ( cust_bill_pkg.pkgpart_override = ? OR cust_pkg.pkgpart = ? )
103     AND (
104       ( cust_bill_pay._date >= ? AND cust_bill_pay._date < ? )
105       OR cust_bill_pay.paynum IS NULL
106     );
107 ";
108
109 # Preserving this oddball, unexplained epoch substitution
110 $end = '' if $end == 4294967295;
111
112 my @bind_values = (
113     $agentnum ? $agentnum : (),
114     $pkgpart,
115     $pkgpart,
116     $begin || 0,
117     $end || time(),
118 );
119
120 if ( $DEBUG ) {
121   warn "\$sql_statement: $sql_statement\n";
122   warn "\@bind_values: ".join(', ',@bind_values)."\n";
123 }
124
125 my $sth = dbh->prepare( $sql_statement );
126 $sth->execute( @bind_values ) || die $sth->errstr;
127 my $row = $sth->fetchrow_hashref;
128
129 my %report = (
130   e911_access_lines => $row->{quantity} || 0,
131
132   fees_charged => sprintf(
133     "%.2f",
134     ( $row->{setup} + $row->{recur} ) || 0,
135   ),
136
137   fees_collected => sprintf(
138     "%.2f",
139     ( $row->{amount} || 0 ),
140   ),
141 );
142
143 # Does everybody use this 1% admin fee?  Should this be configurable?
144 $report{admin_fee} = sprintf( "%.2f", $report{fees_collected} * 0.01 );
145 $report{e911_amount_due} = $report{fees_collected} - $report{admin_fee};
146
147 my $begin_text =
148   $begin
149     ? DateTime->from_epoch(epoch => $begin)->mdy('/')
150     : mt('Anytime');
151
152 my $end_text =  DateTime->from_epoch(epoch => ( $end || time ))->mdy('/');
153
154 my $legend = FS::agent->by_key($agentnum)->agent . ', ' if $agentnum;
155 if ( $begin && $end ) {
156   $legend .= "$begin_text &#x2194; $end_text";
157 } elsif ( $begin ) {
158   $legend .= mt('After')." $begin_text";
159 } else {
160   $legend .= mt('Through')." $end_text"
161 }
162
163 </%init>