RT# 79353 Update discount report - include waived setup fees
[freeside.git] / httemplate / search / cust_bill_pkg_discount.html
1 <%doc>
2
3 Display the Discount Detail Report:
4
5 Parameters:
6
7  - discount_classnum
8  - usernum
9  - agentnum
10  - beginning
11  - ending
12  - include_waived_setup
13
14 </%doc>
15 <& elements/search.html,
16   title       => 'Discounts',
17   name        => 'discounts',
18   query       => $query,
19   count_query => $count_query,
20   count_addl  => [ $money_char . '%.2f total' ],
21
22   header => [
23     qw(
24       Discount
25       Class
26       Amount
27       Months
28       Package
29       Invoice
30       Date
31     ),
32     FS::UI::Web::cust_header(),
33   ],
34
35   fields => [
36     # Discount
37     sub {
38         if ( $_[0]->pkgdiscountnum ) {
39             # Standard discount, not a waived setup fee
40             my $discount = qsearchs('discount',{
41                 pkgdiscountnum => $_[0]->pkgdiscountnum
42             });
43             return $discount->description;
44         } else {
45             return 'Waive setup fee';
46         }
47     },
48
49     # Class
50     sub {
51         if ( $_[0]->discountnum ) {
52             # Standard discount, not a waived setup fee
53             my $discount = qsearchs('discount',{
54                 discountnum => $_[0]->discountnum
55             });
56             return $discount->classname;
57         } else {
58             return 'n/a';
59         }
60     },
61
62     # Amount
63     sub {
64       sprintf(
65         $money_char.'%.2f',
66         $_[0]->amount ? $_[0]->amount : $_[0]->setup_fee
67       )
68     },
69
70     # Months
71     sub {
72       my $row = shift;
73       if ($row->pkgdiscountnum) {
74         $row->setuprecur eq 'setup'
75           ? 'Setup'
76           : sprintf( '%.2f', $row->months ),
77       } else {
78         return 'Setup';
79       }
80     },
81
82     # Package
83     'pkg',
84
85     # Invoice
86     'invnum',
87
88     # Date
89     sub { time2str('%b %d %Y', $_[0]->_date) },
90
91     # Customer
92     \&FS::UI::Web::cust_fields,
93   ],
94
95   sort_fields => [
96     '',       # Discount
97     '',       # Class
98     'amount', # Amount
99     'months', # Months
100     'pkg',    # Package
101     'invnum', # Invoice
102     '_date',  # Date
103   ],
104
105   links => [
106     '', # Discount
107     '', # Class
108     '', # Amount
109     '', # Months
110     '', # Package
111     [ "${p}view/cust_bill.cgi?", 'invnum' ], # Invoice
112     [ "${p}view/cust_bill.cgi?", 'invnum' ], # Date
113     (   # Customer
114       map {
115         $_ ne 'Cust. Status'
116           ? [ "${p}view/cust_main.cgi?", 'custnum' ]
117           : ''
118       } FS::UI::Web::cust_header()
119     ),
120   ],
121
122   align => 'lcrrlrr'.FS::UI::Web::cust_aligns(),
123   color => [ '','','','','','','',FS::UI::Web::cust_colors() ],
124   style => [ '','','','','','','',FS::UI::Web::cust_styles() ],
125 &>
126 <%init>
127
128 die "access denied"
129   unless $FS::CurrentUser::CurrentUser->access_right('Financial reports');
130
131 my $conf = new FS::Conf;
132
133 # Query building blocks
134 my @select = (qw(
135   cust_bill_pkg_discount.billpkgdiscountnum
136   cust_bill_pkg_discount.pkgdiscountnum
137   cust_bill_pkg_discount.amount
138   cust_bill_pkg_discount.months
139
140   cust_bill.invnum
141   cust_bill._date
142
143   part_pkg.pkg
144
145   cust_main.custnum
146
147   cust_pkg_discount.setuprecur
148   cust_pkg_discount.discountnum
149   cust_pkg.waive_setup),
150
151   "
152   (  SELECT optionvalue
153      FROM part_pkg_option
154      WHERE
155         part_pkg_option.pkgpart = cust_pkg.pkgpart
156         AND optionname = 'setup_fee'
157   ) as setup_fee  ",
158
159   "
160   COALESCE(
161       CAST(cust_bill_pkg_discount.amount AS TEXT),
162       (  SELECT optionvalue
163          FROM part_pkg_option
164          WHERE
165             part_pkg_option.pkgpart = cust_pkg.pkgpart
166             AND optionname = 'setup_fee'
167       )
168   ) as discountorwaive
169   ",
170
171   FS::UI::Web::cust_sql_fields(),
172 );
173
174 my $join = "
175 LEFT JOIN cust_bill_pkg_discount
176   USING (billpkgnum)
177
178 LEFT JOIN cust_pkg_discount
179   ON cust_bill_pkg_discount.pkgdiscountnum = cust_pkg_discount.pkgdiscountnum
180
181 LEFT JOIN cust_pkg
182   ON cust_bill_pkg.pkgnum = cust_pkg.pkgnum
183
184 LEFT JOIN part_pkg
185   USING (pkgpart)
186
187 LEFT JOIN cust_bill USING (invnum)
188
189 LEFT JOIN cust_main
190   ON cust_bill.custnum = cust_main.custnum
191
192 ";
193
194 # Each entry in @where will be joined with AND
195 my @where = (
196
197   # Agent Virtualization
198   $FS::CurrentUser::CurrentUser->agentnums_sql(table => 'cust_main'),
199
200   # Select only rows where there is a discount or waived setup fee
201   "(
202     cust_bill_pkg_discount.billpkgdiscountnum IS NOT NULL
203     OR (
204       cust_pkg.setup = cust_bill_pkg.sdate
205       AND cust_pkg.waive_setup = 'Y'
206     )
207   )",
208
209 );
210
211
212 # Filter: Date Range
213 my($beginning, $ending) = FS::UI::Web::parse_beginning_ending($cgi);
214 push @where, "_date >= $beginning", "_date <= $ending";
215
216
217 # Filter: Agent
218 if ( $cgi->param('agentnum') =~ /^(\d+)$/ ) {
219   push @where, "cust_main.agentnum = $1";
220 }
221
222
223 # Filter: User
224 if ( $cgi->param('usernum') =~ /^(\d+)$/ ) {
225   push @where,
226     "( cust_pkg_discount.usernum = $1 OR cust_pkg_discount.usernum IS NULL )";
227 }
228
229 # Filter: Include waived setup fees
230 if ( !$cgi->param('include_waived_setup') ) {
231   push @where, "cust_bill_pkg_discount.pkgdiscountnum IS NOT NULL";
232 }
233
234 # Filter: Discount Class
235 if ( grep { $_ eq 'discount_classnum' } $cgi->param ) {
236
237 #  my @classnum = ();
238 #  if ( ref($params->{'discount_classnum'}) ) {
239 #
240 #    if ( ref($params->{'discount_classnum'}) eq 'HASH' ) {
241 #      @classnum = grep $params->{'discount_classnum'}{$_}, keys %{ $params->{'discount_classnum'} };
242 #    } elsif ( ref($params->{'discount_classnum'}) eq 'ARRAY' ) {
243 #      @classnum = @{ $params->{'discount_classnum'} };
244 #    } else {
245 #      die 'unhandled discount_classnum ref '. $params->{'discount_classnum'};
246 #    }
247 #
248 #
249 #  } elsif ( $params->{'discount_classnum'} =~ /^(\d*)$/ && $1 ne '0' ) {
250 #    @classnum = ( $1 );
251 #  }
252 #
253 #  if ( @classnum ) {
254
255    if ( $cgi->param('discount_classnum') =~ /^(\d*)$/ && $1 ne '0' ) {
256     my @classnum = ( $1 );
257
258     $join .= ' LEFT JOIN discount USING (discountnum) ';
259
260     my @c_where = ();
261     my @nums = grep $_, @classnum;
262     push @c_where, 'discount.classnum IN ('. join(',',@nums). ')' if @nums;
263     my $null = scalar( grep { $_ eq '' } @classnum );
264     push @c_where, 'discount.classnum IS NULL' if $null;
265
266     if ( scalar(@c_where) == 1 ) {
267       push @where, @c_where;
268     } elsif ( @c_where ) {
269       push @where, ' ( '. join(' OR ', @c_where). ' ) ';
270     }
271
272   }
273
274 }
275
276 # #(package) classnum
277 # # not specified: all classes
278 # # 0: empty class
279 # # N: classnum
280 # my $use_override = $cgi->param('use_override');
281 # if ( $cgi->param('classnum') =~ /^(\d+)$/ ) {
282 #   my $comparison = '';
283 #   if ( $1 == 0 ) {
284 #     $comparison = "IS NULL";
285 #   } else {
286 #     $comparison = "= $1";
287 #   }
288
289 #   if ( $use_override ) {
290 #     push @where, "(
291 #       part_pkg.classnum $comparison AND pkgpart_override IS NULL OR
292 #       override.classnum $comparison AND pkgpart_override IS NOT NULL
293 #     )";
294 #   } else {
295 #     push @where, "part_pkg.classnum $comparison";
296 #   }
297 # }
298
299 my $count_query;
300 if ( $cgi->param('include_waived_setup') ) {
301   $count_query = "
302     SELECT
303       COUNT(*),
304       SUM(
305         COALESCE(
306           cust_bill_pkg_discount.amount,
307           CAST((  SELECT optionvalue
308              FROM part_pkg_option
309              WHERE
310                 part_pkg_option.pkgpart = cust_pkg.pkgpart
311                 AND optionname = 'setup_fee'
312           ) AS NUMERIC )
313         )
314       ) ";
315 } else {
316   $count_query = "SELECT COUNT(*), SUM(cust_bill_pkg_discount.amount)";
317 }
318
319 my $where = ' WHERE '. join(' AND ', @where);
320
321 $count_query .= " FROM cust_bill_pkg $join $where";
322
323 my $query = {
324   'table'     => 'cust_bill_pkg',
325   'addl_from' => $join,
326   'hashref'   => {},
327   'select'    => join(', ', @select ),
328   'extra_sql' => $where,
329   'order_by'  => 'ORDER BY _date, billpkgdiscountnum',
330 };
331
332 my $money_char = $conf->config('money_char') || '$';
333
334 </%init>