1d906473edf2c6e9ac9cdd1ba30a7f815b4be353
[freeside.git] / httemplate / search / report_tax.cgi
1 <& /elements/header.html, $report->title &>
2 <TD ALIGN="right">
3 Download full results<BR>
4 as <A HREF="<% $p.'search/report_tax-xls.cgi?'.$cgi->query_string%>">Excel spreadsheet</A>
5 </TD>
6
7 <STYLE type="text/css">
8 TD.sectionhead {
9   background-color: #777777;
10   color: #ffffff;
11   font-weight: bold;
12   text-align: left;
13 }
14 .grid TH { background-color: #cccccc; padding: 0px 3px 2px }
15 .row0 TD { background-color: #eeeeee; padding: 0px 3px 2px; text-align: right}
16 .row1 TD { background-color: #ffffff; padding: 0px 3px 2px; text-align: right}
17 TD.rowhead { font-weight: bold; text-align: left; padding: 0px 3px }
18 .bigmath { font-size: large; font-weight: bold; font: sans-serif; text-align: center }
19 .total { font-style: italic }
20 </STYLE>
21 <& /elements/table-grid.html &>
22   <THEAD>
23   <TR>
24     <TH ROWSPAN=3></TH>
25     <TH COLSPAN=5>Sales</TH>
26     <TH ROWSPAN=3></TH>
27     <TH ROWSPAN=3>Rate</TH>
28     <TH ROWSPAN=3></TH>
29     <TH ROWSPAN=3>Estimated tax</TH>
30     <TH ROWSPAN=3>Tax invoiced</TH>
31     <TH ROWSPAN=3></TH>
32     <TH ROWSPAN=3>Tax credited</TH>
33     <TH ROWSPAN=3></TH>
34     <TH ROWSPAN=3>Net tax due</TH>
35     <TH ROWSPAN=3></TH>
36     <TH ROWSPAN=3>Tax collected</TH>
37   </TR>
38
39   <TR>
40     <TH ROWSPAN=2>Total</TH>
41     <TH ROWSPAN=1>Non-taxable</TH>
42     <TH ROWSPAN=1>Non-taxable</TH>
43     <TH ROWSPAN=1>Non-taxable</TH>
44     <TH ROWSPAN=2>Taxable</TH>
45   </TR>
46
47   <TR STYLE="font-size:small">
48     <TH>(tax-exempt customer)</TH>
49     <TH>(tax-exempt package)</TH>
50     <TH>(monthly exemption)</TH>
51   </TR>
52   </THEAD>
53
54 % my $rownum = 0;
55 % my $prev_row = { pkgclass => 'DUMMY PKGCLASS' };
56
57   <TBODY>
58 % foreach my $row (@rows) {
59 %   # before anything else: if this row's pkgclass is not the same as the 
60 %   # previous row's, then:
61 %   if ( $row->{pkgclass} ne $prev_row->{pkgclass} ) {
62 %     if ( $rownum > 0 ) { # start a new section
63 %       $rownum = 0;
64   </TBODY><TBODY>
65 %     }
66 %     if ( $params{breakdown}->{pkgclass} ) { # and caption the new section
67   <TR>
68     <TD COLSPAN=19 CLASS="sectionhead">
69       <% $pkgclass_name{$row->{pkgclass}} %>
70     </TD>
71   </TR>
72 %     }
73 %   } # if $row->{pkgclass} ne ...
74
75 %   # construct base links that limit to the tax rates described by this row
76 %   my $rowlink = ';taxnum=' . $row->{taxnums};
77 %   # and also the package class, if we're limiting package class
78 %   if ( $params{breakdown}->{pkgclass} ) {
79 %     $rowlink .= ';classnum=' . ($row->{pkgclass} || 0);
80 %   }
81 %
82 %   if ( $row->{total} ) {
83   </TBODY><TBODY CLASS="total">
84 %   }
85   <TR CLASS="row<% $rownum % 2 %>">
86 %   # Row label
87     <TD CLASS="rowhead"><% $row->{label} |h %></TD>
88     <TD>
89 %   # Total sales
90       <A HREF="<% $saleslink . $rowlink %>">
91         <% $money_sprintf->( $row->{sales} ) %>
92       </A>
93     </TD>
94 %   # Exemptions: customer
95     <TD>
96       <A HREF="<% $saleslink . $rowlink . ';exempt_cust=Y' %>">
97         <% $money_sprintf->( $row->{exempt_cust} ) %>
98       </A>
99     </TD>
100 %   # package
101     <TD>
102       <A HREF="<% $saleslink . $rowlink . ';exempt_pkg=Y' %>">
103         <% $money_sprintf->( $row->{exempt_pkg} ) %>
104       </A>
105     </TD>
106 %   # monthly (note this uses $exemptlink; it's a completely separate report)
107     <TD>
108       <A HREF="<% $exemptlink . $rowlink %>">
109         <% $money_sprintf->( $row->{exempt_monthly} ) %>
110       </A>
111     </TD>
112 %   # taxable sales
113     <TD>
114       <A HREF="<% $saleslink . $rowlink . ";taxable=1" %>">
115         <% $money_sprintf->( $row->{taxable} ) %>
116       </A>
117     </TD>
118     <TD CLASS="bigmath"> &times; </TD>
119     <TD><% $row->{rate} %></TD>
120 %   # estimated tax
121     <TD CLASS="bigmath"> = </TD>
122     <TD>
123 %   if ( $row->{estimated} ) {
124       <% $money_sprintf->( $row->{estimated} ) %>
125 %   }
126     </TD>
127 %   # invoiced tax
128     <TD>
129       <A HREF="<% $taxlink . $rowlink %>">
130         <% $money_sprintf->( $row->{tax} ) %>
131       </A>
132     </TD>
133 %   # credited tax
134     <TD CLASS="bigmath"> &minus; </TD>
135     <TD>
136 %#      <A HREF="<% $creditlink . $rowlink %>"> currently broken
137         <% $money_sprintf->( $row->{credit} ) %>
138 %#      </A>
139     </TD>
140 %   # net tax due
141     <TD CLASS="bigmath"> = </TD>
142     <TD><% $money_sprintf->( $row->{tax} - $row->{credit} ) %></TD>
143 %   # tax collected
144     <TD>&nbsp;</TD>
145     <TD><% $money_sprintf->( $row->{tax_paid} ) %></TD>
146   </TR>
147 %   $rownum++;
148 %   $prev_row = $row;
149 % } # foreach my $row
150 % # at the end of everything
151   </TBODY>
152 % if ( $report->{outside} > 0 ) {
153   <TBODY CLASS="total" STYLE="background-color: #cccccc; line-height: 3">
154     <TR>
155       <TD CLASS="rowhead">
156         <% emt('Out of taxable region') %>
157       </TD>
158       <TD STYLE="text-align: right">
159         <A HREF="<% $saleslink %>;out=1;taxname=<% encode_entities($params{'taxname'}) %>">
160           <% $money_sprintf->( $report->{outside } ) %>
161         </A>
162       </TD>
163       <TD COLSPAN=0></TD>
164     </TR>
165   </TBODY>
166 % }
167 </TABLE>
168
169 <& /elements/footer.html &>
170 <%init>
171
172 die "access denied"
173   unless $FS::CurrentUser::CurrentUser->access_right('Financial reports');
174
175 my $DEBUG = $cgi->param('debug') || 0;
176
177 my $conf = new FS::Conf;
178
179 my($beginning, $ending) = FS::UI::Web::parse_beginning_ending($cgi);
180
181 my %params = (
182   beginning => $beginning,
183   ending    => $ending,
184 );
185 $params{country} = $cgi->param('country');
186 $params{debug}   = $DEBUG;
187 $params{breakdown} = { map { $_ => 1 } $cgi->param('breakdown') };
188
189 my $agentname;
190 if ( $cgi->param('agentnum') =~ /^(\d+)$/ ) {
191   my $agent = FS::agent->by_key($1) or die "unknown agentnum $1";
192   $params{agentnum} = $1;
193   $agentname = $agent->agentname;
194 }
195
196 # allow anything in here; FS::Report::Tax will treat it as unsafe
197 if ( length($cgi->param('taxname')) ) {
198   $params{taxname} = $cgi->param('taxname');
199 } else {
200   die "taxname required";
201 }
202
203 if ( $cgi->param('credit_date') eq 'cust_credit_bill' ) {
204   $params{credit_date} = 'cust_credit_bill';
205 } else {
206   $params{credit_date} = 'cust_bill';
207 }
208
209 warn "PARAMS:\n".Dumper(\%params)."\n\n" if $DEBUG;
210
211 my $report = FS::Report::Tax->report_internal(%params);
212 my @rows = $report->table; # array of hashrefs
213
214 my $money_char = $conf->config('money_char') || '$';
215 my $money_sprintf = sub {
216   $money_char. sprintf('%.2f', shift);
217 };
218
219 my $dateagentlink = "begin=$beginning;end=$ending";
220 if ( $params{agentnum} ) {
221   $dateagentlink .= ';agentnum=' . $params{agentnum};
222 }
223 my $saleslink  = $p. "search/cust_bill_pkg.cgi?$dateagentlink;nottax=1";
224 my $taxlink    = $p. "search/cust_bill_pkg.cgi?$dateagentlink;istax=1";
225 my $exemptlink = $p. "search/cust_tax_exempt_pkg.cgi?$dateagentlink";
226 #my $creditlink = $p. "search/cust_bill_pkg.cgi?$dateagentlink;credit=1;istax=1";
227 #if ( $params{'credit_date'} eq 'cust_credit_bill' ) {
228 #  $creditlink =~ s/begin/credit_begin/;
229 #  $creditlink =~ s/end/credit_end/;
230 #}
231 my $creditlink = ''; # disabled until we find a sane way to do this
232
233 my %pkgclass_name = map { $_->classnum, $_->classname } qsearch('pkg_class');
234 $pkgclass_name{''} = 'Unclassified';
235
236 </%init>