optimize rate display, RT#72030
[freeside.git] / httemplate / edit / elements / rate_detail.html
1 <%doc>
2 <% include('/edit/elements/rate_detail.html',
3     # required
4     'ratenum'     => '1',
5     
6     # optional
7     'regionnum'   => '25',
8     # or
9     'countrycode' => '237',
10 ) %>
11
12 If regionnum is specified, this produces column headers plus 
13 one row of rate details for that region (in all time periods).
14 Otherwise, there's one row for each region in the specified 
15 countrycode (or each region anywhere, if there is no countrycode),
16 with row headers showing the region name and prefixes.
17
18 </%doc>
19 <% include('/elements/table-grid.html') %>
20 <TR>
21 % my $col = 0;
22 % foreach (@header) {
23 %   my $hlink = $hlinks[$col];
24   <TH CLASS   = "grid",
25       BGCOLOR = "#cccccc">
26   <% $hlink ? qq!<A HREF="$hlink">$_</A>! : $_ %>
27   </TH>
28 %   $col++;
29 % } #foreach @header
30 </TR><TR>
31 % my $row = 0;
32 % foreach my $r (@rows) {
33 %   $col = 0;
34 %   if ( !$opt{'regionnum'} ) {
35 %     $region = $r;
36 %     foreach ($r->regionname, $r->prefixes_short_sql) {
37   <TD>
38     <A HREF="<% $p.'edit/rate_region.cgi?regionnum='.$r->regionnum %>"><% $_ |h %></A>
39   </TD>
40 %     }
41 %   }
42 %   elsif ( !$opt{'ratenum'} ) {
43 %     $rate = $r;
44   <TD>
45     <A HREF="<% $p.'edit/rate.cgi?ratenum='.$r->ratenum %>"><% $r->ratename %></A>
46   </TD>
47 %   }
48 %   foreach my $rate_time (@rate_time, '') {
49   <TD>
50     <& .detail_box,
51       detail      => $details[$row][$col],
52       ratetimenum => ($rate_time ? $rate_time->ratetimenum : ''),
53       cdrtypenum  => $cdrtypenum,
54       regionnum   => $region->regionnum,
55       ratenum     => $rate->ratenum
56     &>
57 %     $col++;
58   </TD>
59 %   } # foreach @rate_time
60 </TR>
61 %   $row++;
62 % }# foreach @rate_region
63 % if ( !$opt{regionnum} ) {
64 %   # global default for this cdrtypenum
65 <TR>
66   <TD COLSPAN=2 STYLE="padding-top: 10px">
67     <B>Global default</B> (for calls not matching any prefix)
68   </TD>
69   <TD STYLE="padding-top: 10px">
70 %   # default rate: set a null region for this cdr type
71     <B>
72     <& .detail_box,
73       detail      => $rate->default_detail($cdrtypenum),
74       ratetimenum => '',
75       cdrtypenum  => $cdrtypenum,
76       regionnum   => '',
77       ratenum     => $rate->ratenum
78     &>
79     </B>
80   </TD>
81 % }
82 </TABLE>
83 <%def .detail_box>
84 <%args>
85 $detail => undef,
86 $ratetimenum
87 $cdrtypenum
88 $regionnum
89 $ratenum
90 </%args>
91 % if ($detail) {
92       <TABLE CLASS="inv" STYLE="border:none">
93       <TR><TD><% edit_link($detail) %>
94 %   if ( $detail->min_charge > 0 or $detail->conn_charge > 0) {
95               <% $money_char.$detail->min_charge %>
96               <% $detail->sec_granularity ? ' / minute':' / call' %>
97 %             if ( $detail->min_cost ) {
98                 (<% $money_char.$detail->min_cost %> cost)
99 %             }
100 %     if ( $detail->upstream_mult_charge > 0
101 %          or $detail->upstream_mult_cost > 0) {
102               <BR>+ 
103 %     }
104 %   }
105 %   if ( $detail->upstream_mult_charge > 0 
106 %        or $detail->upstream_mult_cost > 0) {
107               <% $detail->upstream_mult_charge %> &times; upstream price
108 %             if ( $detail->upstream_mult_cost > 0 ) {
109               (<% $detail->upstream_mult_cost %> cost)
110 %             }
111 %   }
112 %   if ( $detail->upstream_mult_charge == 0
113 %        and $detail->min_charge == 0 
114 %        and $detail->conn_charge == 0 ) {
115               Free
116 %   }
117       <% $edit_hint %></A>
118       </TD></TR>
119       <% granularity_detail($detail) %>
120       <% min_included_detail($detail) %>
121       <% conn_charge_detail($detail) %>
122       <TR><TD><% ( $ratetimenum || $cdrtypenum ) ? delete_link($detail) : '' %>
123       </TD></TR>
124     </TABLE>
125 % } else {
126     <% add_link($ratenum, $regionnum, $ratetimenum, $cdrtypenum) %>
127 % }
128 </%def>
129 <%once>
130
131 tie my %granularity, 'Tie::IxHash', FS::rate_detail::granularities();
132 tie my %conn_secs,   'Tie::IxHash', FS::rate_detail::conn_secs();
133
134 my $conf = new FS::Conf;
135 my $money_char = $conf->config('money_char') || '$';
136
137 sub small {
138   '<FONT SIZE="-1">'.shift.'</FONT>'
139 }
140 my $edit_hint = small('(edit)');
141
142 sub edit_link {
143   my $rate_detail = shift;
144   my $ratedetailnum = $rate_detail->ratedetailnum;
145   '<A HREF="javascript:void(0);" onclick="'.
146   include( '/elements/popup_link_onclick.html',
147              'action'      => "${p}edit/rate_detail.html?$ratedetailnum",
148              'actionlabel' => 'Edit rate',
149              'height'      => 550,
150              'width'       => 580,
151              #default# 'width'       => 540,
152              #default# 'color'       => '#333399',
153          ) . '">'
154 }
155
156 sub add_link {
157   my ($ratenum, $regionnum, $ratetimenum, $cdrtypenum) = @_;
158   '<A HREF="javascript:void(0);" onclick="'.
159   include( '/elements/popup_link_onclick.html',
160              'action'      => "${p}edit/rate_detail.html?ratenum=".
161                                   $ratenum.
162                                ';dest_regionnum='.
163                                   $regionnum.
164                                ';ratetimenum='.
165                                  ($ratetimenum || '').
166                                ";cdrtypenum=$cdrtypenum",
167              'actionlabel' => 'Add rate',
168              'width'       => 580,
169              'height'      => 550,
170              ).'">'.small('(add)').'</A>'
171 }
172
173 sub delete_link {
174   my $rate_detail = shift;
175   my $ratedetailnum = $rate_detail->ratedetailnum;
176   my $onclick = include( '/elements/popup_link_onclick.html',
177              'action'      => "${p}misc/delete-rate_detail.html?$ratedetailnum",
178              'actionlabel' => 'Delete rate',
179              'width'       => 510,
180              'height'      => 315,
181              'frame'       => 'top',
182              );
183   $onclick = "if(confirm('Delete this rate?')) { $onclick }";
184   qq!<A HREF="javascript:void(0);" onclick="$onclick">!.small('(delete)').'</A>'
185 }
186
187 sub granularity_detail {
188   my $rate_detail = shift;
189   if(
190       $rate_detail->sec_granularity != 60 
191       && $rate_detail->sec_granularity > 0
192       && $rate_detail->min_charge > 0) {
193     '<TR><TD>'.
194     small('in '.$granularity{$rate_detail->sec_granularity}.' increments').
195     '</TD></TR>';
196   }
197   else { '' }
198 }
199
200 sub min_included_detail {
201   my $rate_detail = shift;
202   if($rate_detail->min_included) {
203     '<TR><TD>'.
204     small( $rate_detail->min_included . 
205             ($rate_detail->sec_granularity ? 
206              ' minutes included' : 
207              ' calls included') ).
208     '</TD></TR>'
209   }
210   else { '' }
211 }
212
213 sub conn_charge_detail {
214   my $rate_detail = shift;
215   if($rate_detail->conn_charge > 0) {
216   #return '' unless $rate_detail->conn_charge > 0 || $rate_detail->conn_sec;
217     '<TR><TD>'.
218     small( $money_char. $rate_detail->conn_charge.
219              ( $rate_detail->conn_cost
220                  ? ' ('. $money_char.$rate_detail->conn_cost. ' cost)'
221                  : ''
222              ).
223            ' for '. $conn_secs{$rate_detail->conn_sec}
224     ).
225     '</TD></TR>'
226   }
227   else { '' }
228 }
229
230 </%once>
231 <%init>
232
233 die "access denied"
234   unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
235
236 my %opt = @_;
237 my $ratenum = $opt{'ratenum'} || '';
238 my $regionnum = $opt{'regionnum'} || '';
239 my $cdrtypenum = $opt{'cdrtypenum'} || '';
240
241 # either of these, if the $opt isn't passed, will be set to the 
242 # correct object when generating each row.
243 my $rate = qsearchs('rate', { 'ratenum' => $ratenum } ) if $ratenum;
244 my $region = qsearchs('rate_region', { 'regionnum' => $regionnum }) if $regionnum;
245
246 my @rate_time = qsearch('rate_time', {});
247 my @header = (
248   map( { $_->ratetimename } @rate_time ),
249   'Default rate');
250 my @hlinks = map( {$p.'edit/rate_time.cgi?'.$_->ratetimenum} @rate_time ), '';
251 my @rtns = ( map( { $_->ratetimenum } @rate_time ), '' );
252
253 my @details;
254 my @rows;
255
256 my %rate_region = (
257   'select'    => 'rate_region.*, '.
258                  "STRING_AGG(countrycode || ' ' || npa, ',') AS prefixes",
259   'table'     => 'rate_region',
260   'addl_from' => 'LEFT JOIN rate_prefix USING ( regionnum ) ',
261   'extra_sql' => 'GROUP BY ( rate_region.regionnum )',
262   'order_by'  => 'ORDER BY ( regionname )',
263 );
264
265 if ( $ratenum ) {
266
267   if ( $regionnum ) {
268
269     @rows = qsearch({
270       %rate_region,
271       'hashref' => { ratenum => $ratenum, regionnum => $regionnum },
272     });
273
274   } else {
275
276     if ( $opt{'countrycode'} ) {
277       $rate_region{extra_sql} = 
278                "WHERE 0 < ( 
279                     SELECT COUNT(*) FROM rate_prefix
280                     WHERE rate_prefix.regionnum = rate_region.regionnum
281                     AND countrycode = '$opt{countrycode}' 
282                 ) ".
283                $rate_region{extra_sql};
284     }
285     @rows = qsearch({ %rate_region,
286                       hashref   => {},
287                    });
288     #die "no region found" if !@rows;
289
290     unshift @header, 'Region', 'Prefix(es)';
291     unshift @hlinks, '', '';
292
293   }
294
295   foreach my $region (@rows) {
296      push @details, [ map { qsearchs('rate_detail', 
297                                       { 'ratenum'        => $ratenum,
298                                         'dest_regionnum' => $region->regionnum,
299                                         'cdrtypenum'     => $cdrtypenum,
300                                         'ratetimenum'    => $_ } ) or ''
301                           } @rtns
302                     ];
303   }
304
305 } elsif ( $regionnum ) {
306
307   @rows = qsearch('rate', {}) or die "no rate plans found";
308   unshift @header, 'Rate plan';
309   unshift @hlinks, '';
310   foreach my $rate (@rows) {
311     push @details, [ map { qsearchs('rate_detail',
312                                      { 'ratenum'        => $rate->ratenum,
313                                        'dest_regionnum' => $regionnum,
314                                        'cdrtypenum'     => $cdrtypenum,
315                                        'ratetimenum'    => $_ } ) or ''
316                          } @rtns
317                    ];
318   }
319
320 } else {
321   die "no ratenum or regionnum specified";
322 }
323
324 </%init>