+ my %hash = (
+ 'ratenum' => $self->ratenum,
+ 'dest_regionnum' => $regionnum,
+ );
+
+ # find all rates matching ratenum, regionnum, cdrtypenum
+ my @details = qsearch( 'rate_detail', {
+ %hash,
+ 'cdrtypenum' => $cdrtypenum
+ });
+ # failing that, return the global default for this plan with the correct
+ # cdrtypenum (skips weektime processing)
+ if ( !@details and $cdrtypenum ) {
+ my $detail = $self->default_detail($cdrtypenum);
+ return $detail if $detail;
+ }
+ # failing that, find all rates maching ratenum, regionnum and null cdrtypenum
+ # (these can have weektime stuff)
+ if ( !@details and $cdrtypenum ) {
+ @details = qsearch( 'rate_detail', {
+ %hash,
+ 'cdrtypenum' => ''
+ });
+ }
+ # find one of those matching weektime
+ if ( defined($weektime) ) {
+ my @exact = grep {
+ my $rate_time = $_->rate_time;
+ $rate_time && $rate_time->contains($weektime)
+ } @details;
+ if ( @exact == 1 ) {
+ return $exact[0];
+ }
+ elsif ( @exact > 1 ) {
+ die "overlapping rate_detail times (region $regionnum, time $weektime)\n"
+ }
+ # else @exact == 0
+ }
+ # if not found or there is no weektime, find one matching null weektime
+ foreach (@details) {
+ return $_ if $_->ratetimenum eq '';
+ }
+ # if still nothing, return the global default rate for this plan
+ return $self->default_detail('');