2022
[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                 discountnum => $_[0]->discountnum
42             }) || return 'Bad discountnum '.$_[0]->pkgdiscountnum;
43             return encode_entities $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 encode_entities $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 &>
127 <%init>
128
129 die "access denied"
130   unless $FS::CurrentUser::CurrentUser->access_right('Financial reports');
131
132 my $conf = new FS::Conf;
133
134 # Query building blocks
135 my @select = (qw(
136   cust_bill_pkg_discount.billpkgdiscountnum
137   cust_bill_pkg_discount.pkgdiscountnum
138   cust_bill_pkg_discount.amount
139   cust_bill_pkg_discount.months
140
141   cust_bill.invnum
142   cust_bill._date
143
144   part_pkg.pkg
145
146   cust_main.custnum
147
148   cust_pkg_discount.setuprecur
149   cust_pkg_discount.discountnum
150   cust_pkg.waive_setup),
151
152   "
153   (  SELECT optionvalue
154      FROM part_pkg_option
155      WHERE
156         part_pkg_option.pkgpart = cust_pkg.pkgpart
157         AND optionname = 'setup_fee'
158   ) as setup_fee  ",
159
160   "
161   COALESCE(
162       CAST(cust_bill_pkg_discount.amount AS TEXT),
163       (  SELECT optionvalue
164          FROM part_pkg_option
165          WHERE
166             part_pkg_option.pkgpart = cust_pkg.pkgpart
167             AND optionname = 'setup_fee'
168       )
169   ) as discountorwaive
170   ",
171
172   FS::UI::Web::cust_sql_fields(),
173 );
174
175 my $join = "
176 LEFT JOIN cust_bill_pkg_discount
177   USING (billpkgnum)
178
179 LEFT JOIN cust_pkg_discount
180   ON cust_bill_pkg_discount.pkgdiscountnum = cust_pkg_discount.pkgdiscountnum
181
182 LEFT JOIN cust_pkg
183   ON cust_bill_pkg.pkgnum = cust_pkg.pkgnum
184
185 LEFT JOIN part_pkg
186   USING (pkgpart)
187
188 LEFT JOIN cust_bill USING (invnum)
189
190 LEFT JOIN cust_main
191   ON cust_bill.custnum = cust_main.custnum
192
193 ";
194
195 # Each entry in @where will be joined with AND
196 my @where = (
197
198   # Agent Virtualization
199   $FS::CurrentUser::CurrentUser->agentnums_sql(table => 'cust_main'),
200
201   # Select only rows where there is a discount or waived setup fee
202   "(
203     cust_bill_pkg_discount.billpkgdiscountnum IS NOT NULL
204     OR (
205       cust_pkg.setup = cust_bill_pkg.sdate
206       AND cust_pkg.waive_setup = 'Y'
207     )
208   )",
209
210 );
211
212
213 # Filter: Date Range
214 my($beginning, $ending) = FS::UI::Web::parse_beginning_ending($cgi);
215 push @where, "_date >= $beginning", "_date <= $ending";
216
217
218 # Filter: Agent
219 if ( $cgi->param('agentnum') =~ /^(\d+)$/ ) {
220   push @where, "cust_main.agentnum = $1";
221 }
222
223
224 # Filter: User
225 if ( $cgi->param('usernum') =~ /^(\d+)$/ ) {
226   push @where,
227     "( cust_pkg_discount.usernum = $1 OR cust_pkg_discount.usernum IS NULL )";
228 }
229
230 # Filter: Include waived setup fees
231 if ( $cgi->param('include_waived_setup') ) {
232   # Filter a hidden fee attached to a package with a waived setup fee from
233   # causing the waived-fee for that package to be double-counted
234   push @where, 'cust_bill_pkg.pkgpart_override IS NULL';
235 } else {
236   push @where, "cust_bill_pkg_discount.pkgdiscountnum IS NOT NULL";
237 }
238
239 # Filter: Discount Class
240 if ( grep { $_ eq 'discount_classnum' } $cgi->param ) {
241
242 #  my @classnum = ();
243 #  if ( ref($params->{'discount_classnum'}) ) {
244 #
245 #    if ( ref($params->{'discount_classnum'}) eq 'HASH' ) {
246 #      @classnum = grep $params->{'discount_classnum'}{$_}, keys %{ $params->{'discount_classnum'} };
247 #    } elsif ( ref($params->{'discount_classnum'}) eq 'ARRAY' ) {
248 #      @classnum = @{ $params->{'discount_classnum'} };
249 #    } else {
250 #      die 'unhandled discount_classnum ref '. $params->{'discount_classnum'};
251 #    }
252 #
253 #
254 #  } elsif ( $params->{'discount_classnum'} =~ /^(\d*)$/ && $1 ne '0' ) {
255 #    @classnum = ( $1 );
256 #  }
257 #
258 #  if ( @classnum ) {
259
260    if ( $cgi->param('discount_classnum') =~ /^(\d*)$/ && $1 ne '0' ) {
261     my @classnum = ( $1 );
262
263     $join .= ' LEFT JOIN discount USING (discountnum) ';
264
265     my @c_where = ();
266     my @nums = grep $_, @classnum;
267     push @c_where, 'discount.classnum IN ('. join(',',@nums). ')' if @nums;
268     my $null = scalar( grep { $_ eq '' } @classnum );
269     push @c_where, 'discount.classnum IS NULL' if $null;
270
271     if ( scalar(@c_where) == 1 ) {
272       push @where, @c_where;
273     } elsif ( @c_where ) {
274       push @where, ' ( '. join(' OR ', @c_where). ' ) ';
275     }
276
277   }
278
279 }
280
281 # #(package) classnum
282 # # not specified: all classes
283 # # 0: empty class
284 # # N: classnum
285 # my $use_override = $cgi->param('use_override');
286 # if ( $cgi->param('classnum') =~ /^(\d+)$/ ) {
287 #   my $comparison = '';
288 #   if ( $1 == 0 ) {
289 #     $comparison = "IS NULL";
290 #   } else {
291 #     $comparison = "= $1";
292 #   }
293
294 #   if ( $use_override ) {
295 #     push @where, "(
296 #       part_pkg.classnum $comparison AND pkgpart_override IS NULL OR
297 #       override.classnum $comparison AND pkgpart_override IS NOT NULL
298 #     )";
299 #   } else {
300 #     push @where, "part_pkg.classnum $comparison";
301 #   }
302 # }
303
304 my $count_query;
305 if ( $cgi->param('include_waived_setup') ) {
306   $count_query = "
307     SELECT
308       COUNT(*),
309       SUM(
310         COALESCE(
311           cust_bill_pkg_discount.amount,
312           CAST((  SELECT optionvalue
313              FROM part_pkg_option
314              WHERE
315                 part_pkg_option.pkgpart = cust_pkg.pkgpart
316                 AND optionname = 'setup_fee'
317           ) AS NUMERIC )
318         )
319       ) ";
320 } else {
321   $count_query = "SELECT COUNT(*), SUM(cust_bill_pkg_discount.amount)";
322 }
323
324 my $where = ' WHERE '. join(' AND ', @where);
325
326 $count_query .= " FROM cust_bill_pkg $join $where";
327
328 my $query = {
329   'table'     => 'cust_bill_pkg',
330   'addl_from' => $join,
331   'hashref'   => {},
332   'select'    => join(', ', @select ),
333   'extra_sql' => $where,
334   'order_by'  => 'ORDER BY _date, billpkgdiscountnum',
335 };
336
337 my $money_char = $conf->config('money_char') || '$';
338
339 </%init>