2 <% include('/edit/elements/rate_detail.html',
9 'countrycode' => '237',
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.
19 <% include('/elements/table-grid.html') %>
23 % my $hlink = $hlinks[$col];
26 <% $hlink ? qq!<A HREF="$hlink">$_</A>! : $_ %>
32 % foreach my $r (@rows) {
34 % if ( !$opt{'regionnum'} ) {
36 % foreach ($r->regionname, $r->prefixes_short_sql) {
38 <A HREF="<% $p.'edit/rate_region.cgi?regionnum='.$r->regionnum %>"><% $_ |h %></A>
42 % elsif ( !$opt{'ratenum'} ) {
45 <A HREF="<% $p.'edit/rate.cgi?ratenum='.$r->ratenum %>"><% $r->ratename %></A>
48 % foreach my $rate_time (@rate_time, '') {
51 detail => $details[$row][$col],
52 ratetimenum => ($rate_time ? $rate_time->ratetimenum : ''),
53 cdrtypenum => $cdrtypenum,
54 regionnum => $region->regionnum,
55 ratenum => $rate->ratenum
59 % } # foreach @rate_time
62 % }# foreach @rate_region
63 % if ( !$opt{regionnum} ) {
64 % # global default for this cdrtypenum
66 <TD COLSPAN=2 STYLE="padding-top: 10px">
67 <B>Global default</B> (for calls not matching any prefix)
69 <TD STYLE="padding-top: 10px">
70 % # default rate: set a null region for this cdr type
73 detail => $rate->default_detail($cdrtypenum),
75 cdrtypenum => $cdrtypenum,
77 ratenum => $rate->ratenum
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)
100 % if ( $detail->upstream_mult_charge > 0
101 % or $detail->upstream_mult_cost > 0) {
105 % if ( $detail->upstream_mult_charge > 0
106 % or $detail->upstream_mult_cost > 0) {
107 <% $detail->upstream_mult_charge %> × upstream price
108 % if ( $detail->upstream_mult_cost > 0 ) {
109 (<% $detail->upstream_mult_cost %> cost)
112 % if ( $detail->upstream_mult_charge == 0
113 % and $detail->min_charge == 0
114 % and $detail->conn_charge == 0 ) {
119 <% granularity_detail($detail) %>
120 <% min_included_detail($detail) %>
121 <% conn_charge_detail($detail) %>
122 <TR><TD><% ( $ratetimenum || $cdrtypenum ) ? delete_link($detail) : '' %>
126 <% add_link($ratenum, $regionnum, $ratetimenum, $cdrtypenum) %>
131 tie my %granularity, 'Tie::IxHash', FS::rate_detail::granularities();
132 tie my %conn_secs, 'Tie::IxHash', FS::rate_detail::conn_secs();
134 my $conf = new FS::Conf;
135 my $money_char = $conf->config('money_char') || '$';
138 '<FONT SIZE="-1">'.shift.'</FONT>'
140 my $edit_hint = small('(edit)');
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',
151 #default# 'width' => 540,
152 #default# 'color' => '#333399',
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=".
165 ($ratetimenum || '').
166 ";cdrtypenum=$cdrtypenum",
167 'actionlabel' => 'Add rate',
170 ).'">'.small('(add)').'</A>'
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',
183 $onclick = "if(confirm('Delete this rate?')) { $onclick }";
184 qq!<A HREF="javascript:void(0);" onclick="$onclick">!.small('(delete)').'</A>'
187 sub granularity_detail {
188 my $rate_detail = shift;
190 $rate_detail->sec_granularity != 60
191 && $rate_detail->sec_granularity > 0
192 && $rate_detail->min_charge > 0) {
194 small('in '.$granularity{$rate_detail->sec_granularity}.' increments').
200 sub min_included_detail {
201 my $rate_detail = shift;
202 if($rate_detail->min_included) {
204 small( $rate_detail->min_included .
205 ($rate_detail->sec_granularity ?
206 ' minutes included' :
207 ' calls included') ).
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;
218 small( $money_char. $rate_detail->conn_charge.
219 ( $rate_detail->conn_cost
220 ? ' ('. $money_char.$rate_detail->conn_cost. ' cost)'
223 ' for '. $conn_secs{$rate_detail->conn_sec}
234 unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
237 my $ratenum = $opt{'ratenum'} || '';
238 my $regionnum = $opt{'regionnum'} || '';
239 my $cdrtypenum = $opt{'cdrtypenum'} || '';
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;
246 my @rate_time = qsearch('rate_time', {});
248 map( { $_->ratetimename } @rate_time ),
250 my @hlinks = map( {$p.'edit/rate_time.cgi?'.$_->ratetimenum} @rate_time ), '';
251 my @rtns = ( map( { $_->ratetimenum } @rate_time ), '' );
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 )',
271 'hashref' => { ratenum => $ratenum, regionnum => $regionnum },
276 if ( $opt{'countrycode'} ) {
277 $rate_region{extra_sql} =
279 SELECT COUNT(*) FROM rate_prefix
280 WHERE rate_prefix.regionnum = rate_region.regionnum
281 AND countrycode = '$opt{countrycode}'
283 $rate_region{extra_sql};
285 @rows = qsearch({ %rate_region,
288 #die "no region found" if !@rows;
290 unshift @header, 'Region', 'Prefix(es)';
291 unshift @hlinks, '', '';
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 ''
305 } elsif ( $regionnum ) {
307 @rows = qsearch('rate', {}) or die "no rate plans found";
308 unshift @header, 'Rate plan';
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 ''
321 die "no ratenum or regionnum specified";