add plan & pricing to package browse...
[freeside.git] / httemplate / browse / part_pkg.cgi
1 <% include( 'elements/browse.html',
2                  'title'              => 'Package Definitions',
3                  'html_init'          => $html_init,
4                  'name'               => 'package definitions',
5                  'disableable'        => 1,
6                  'disabled_statuspos' => 3,
7                  'agent_virt'         => 1,
8                  'agent_null_right'   => 'Edit global package definitions',
9                  'agent_pos'          => 5,
10                  'query'              => { 'select'   => $select,
11                                            'table'    => 'part_pkg',
12                                            'hashref'  => {},
13                                            'order_by' => "ORDER BY $orderby",
14                                          },
15                  'count_query'        => $count_query,
16                  'header'             => \@header,
17                  'fields'             => \@fields,
18                  'links'              => \@links,
19                  'align'              => $align,
20              )
21 %>
22 <%init>
23
24 die "access denied"
25   unless $FS::CurrentUser::CurrentUser->access_right('Edit package definitions')
26       || $FS::CurrentUser::CurrentUser->access_right('Edit global package definitions');
27
28 my $select = '*';
29 my $orderby = 'pkgpart';
30 if ( $cgi->param('active') ) {
31
32   $orderby = 'num_active DESC';
33 }
34   $select = "
35
36     *,
37
38     ( SELECT COUNT(*) FROM cust_pkg WHERE cust_pkg.pkgpart = part_pkg.pkgpart
39        AND ( cancel IS NULL OR cancel = 0 )
40        AND ( susp IS NULL OR susp = 0 )
41     ) AS num_active,
42
43     ( SELECT COUNT(*) FROM cust_pkg WHERE cust_pkg.pkgpart = part_pkg.pkgpart
44         AND ( cancel IS NULL OR cancel = 0 )
45         AND susp IS NOT NULL AND susp != 0
46     ) AS num_suspended,
47
48     ( SELECT COUNT(*) FROM cust_pkg WHERE cust_pkg.pkgpart = part_pkg.pkgpart
49         AND cancel IS NOT NULL AND cancel != 0
50     ) AS num_cancelled
51
52   ";
53
54 #}
55
56 my $conf = new FS::Conf;
57 my $taxclasses = $conf->exists('enable_taxclasses');
58 my $money_char = $conf->config('money_char') || '$';
59
60 my $html_init;
61 #unless ( $cgi->param('active') ) {
62   $html_init = qq!
63     One or more service definitions are grouped together into a package 
64     definition and given pricing information.  Customers purchase packages
65     rather than purchase services directly.<BR><BR>
66     <A HREF="${p}edit/part_pkg.cgi"><I>Add a new package definition</I></A>
67     <BR><BR>
68   !;
69 #}
70
71 # ------
72
73 my $link = [ $p.'edit/part_pkg.cgi?', 'pkgpart' ];
74
75 my @header = ( '#', 'Package', 'Comment' );
76 my @fields = ( 'pkgpart', 'pkg', 'comment' );
77 my $align = 'rll';
78 my @links = ( $link, $link, '' );
79
80 unless ( 0 ) { #already showing only one class or something?
81   push @header, 'Class';
82   push @fields, sub { shift->classname || '(none)'; };
83   $align .= 'l';
84 }
85
86 tie my %plans, 'Tie::IxHash', %{ FS::part_pkg::plan_info() };
87
88 tie my %plan_labels, 'Tie::IxHash',
89   map {  $_ => ( $plans{$_}->{'shortname'} || $plans{$_}->{'name'} ) }
90       keys %plans;
91
92 push @header, 'Pricing';
93 $align .= 'r'; #?
94 push @fields, sub {
95   my $part_pkg = shift;
96
97   [
98     [
99       { data=>$plan_labels{$part_pkg->plan},
100         align=>'center'
101       },
102     ],
103     [
104       { data=>$money_char.
105               sprintf('%.2f setup', $part_pkg->option('setup_fee') ),
106         align=>'right'
107       },
108     ],
109     [
110       { data=>( $part_pkg->freq ne '0'
111                   ? $money_char.sprintf('%.2f ', $part_pkg->option('recur_fee') )
112                   : ''
113               ).
114               $part_pkg->freq_pretty,
115         align=>'right'
116       },
117     ],
118   ];
119
120 #  $plan_labels{$part_pkg->plan}.'<BR>'.
121 #    $money_char.sprintf('%.2f setup<BR>', $part_pkg->option('setup_fee') ).
122 #    ( $part_pkg->freq ne '0'
123 #      ? $money_char.sprintf('%.2f ', $part_pkg->option('recur_fee') )
124 #      : ''
125 #    ).
126 #    $part_pkg->freq_pretty; #.'<BR>'
127 };
128
129 #if ( $cgi->param('active') ) {
130   push @header, 'Customer<BR>packages';
131   my %col = (
132     'active'          => '00CC00',
133     'suspended'       => 'FF9900',
134     'cancelled'       => 'FF0000',
135     #'one-time charge' => '000000',
136     'charge'          => '000000',
137   );
138   my $cust_pkg_link = $p. 'search/cust_pkg.cgi?pkgpart=';
139   push @fields, sub { my $part_pkg = shift;
140                       [
141                         map {
142                               my $magic = $_;
143                               my $label = $_;
144                               if ( $magic eq 'active' && $part_pkg->freq == 0 ) {
145                                 $magic = 'inactive';
146                                 #$label = 'one-time charge',
147                                 $label = 'charge',
148                               }
149                           
150                               [
151                                 {
152                                  'data'  => '<B><FONT COLOR="#'. $col{$label}. '">'.
153                                             $part_pkg->get("num_$_").
154                                             '</FONT></B>',
155                                  'align' => 'right',
156                                 },
157                                 {
158                                  'data'  => $label.
159                                               ( $part_pkg->get("num_$_") != 1
160                                                 && $label =~ /charge$/
161                                                   ? 's'
162                                                   : ''
163                                               ),
164                                  'align' => 'left',
165                                  'link'  => ( $part_pkg->get("num_$_")
166                                                 ? $cust_pkg_link.
167                                                   $part_pkg->pkgpart.
168                                                   ";magic=$magic"
169                                                 : ''
170                                             ),
171                                 },
172                               ],
173                             } (qw( active suspended cancelled ))
174                       ]; };
175   $align .= 'r';
176 #}
177
178 if ( $taxclasses ) {
179   push @header, 'Taxclass';
180   push @fields, sub { shift->taxclass() || '&nbsp;'; };
181   $align .= 'l';
182 }
183
184 push @header, 'Plan options',
185               'Services';
186               #'Service', 'Quan', 'Primary';
187
188 push @fields, 
189               sub {
190                     my $part_pkg = shift;
191                     if ( $part_pkg->plan ) {
192
193                       [ map { 
194                               /^(\w+)=(.*)$/; #or something;
195                               [
196                                 { 'data'  => $1,
197                                   'align' => 'right',
198                                 },
199                                 { 'data'  => $part_pkg->format($1,$2),
200                                   'align' => 'left',
201                                 },
202                               ];
203                             }
204                         split(/\n/, $part_pkg->plandata)
205                       ];
206
207                     } else {
208
209                       [ map { [
210                                 { 'data'  => uc($_),
211                                   'align' => 'right',
212                                 },
213                                 {
214                                   'data'  => $part_pkg->$_(),
215                                   'align' => 'left',
216                                 },
217                               ];
218                             }
219                         (qw(setup recur))
220                       ];
221
222                     }
223
224                   },
225
226               sub {
227                     my $part_pkg = shift;
228
229                     [ map  {
230                              my $pkg_svc = $_;
231                              my $part_svc = $pkg_svc->part_svc;
232                              my $svc = $part_svc->svc;
233                              if ( $pkg_svc->primary_svc =~ /^Y/i ) {
234                                $svc = "<B>$svc (PRIMARY)</B>";
235                              }
236                              $svc =~ s/ +/&nbsp;/g;
237
238                              [
239                                {
240                                  'data'  => '<B>'. $pkg_svc->quantity. '</B>',
241                                  'align' => 'right'
242                                },
243                                {
244                                  'data'  => $svc,
245                                  'align' => 'left',
246                                  'link'  => $p. 'edit/part_svc.cgi?'.
247                                             $part_svc->svcpart,
248                                },
249                              ];
250                            }
251                       sort {     $b->primary_svc =~ /^Y/i
252                              <=> $a->primary_svc =~ /^Y/i
253                            }
254                            $part_pkg->pkg_svc
255
256                     ];
257
258                   };
259
260 $align .= 'lrl'; #rr';
261
262 # --------
263
264 my $count_query = 'SELECT COUNT(*) FROM part_pkg WHERE '.
265                     $FS::CurrentUser::CurrentUser->agentnums_sql(
266                       'null_right' => 'Edit global package definitions',
267                     );
268
269 </%init>