X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fpart_pkg%2Fsql_external.pm;h=9bf107b7df314b3b919c8cf698b95794dca6895c;hb=9c2854f48fb79a5534bbb35c4b7c12b2e6acc0a4;hp=4bf9ecbe72871cd04e53795fea33753701cbea3c;hpb=fb4ab1073f0d15d660c6cdc4e07afebf68ef3924;p=freeside.git diff --git a/FS/FS/part_pkg/sql_external.pm b/FS/FS/part_pkg/sql_external.pm index 4bf9ecbe7..9bf107b7d 100644 --- a/FS/FS/part_pkg/sql_external.pm +++ b/FS/FS/part_pkg/sql_external.pm @@ -6,6 +6,14 @@ use vars qw( %info ); use DBI; #use FS::Record qw(qsearch qsearchs); +tie our %query_style, 'Tie::IxHash', ( + 'simple' => 'Simple (a single value for the recurring charge)', + 'detailed' => 'Detailed (multiple rows for invoice details)', +); + +our @detail_cols = ( qw(amount format duration phonenum accountcode + startdate regionname detail) + ); %info = ( 'name' => 'Base charge plus additional fees for external services from a configurable SQL query', 'shortname' => 'External SQL query', @@ -34,17 +42,24 @@ use DBI; 'query' => { 'name' => 'SQL query', 'default' => '', }, + + 'query_style' => { + 'name' => 'Query output style', + 'type' => 'select', + 'select_options' => \%query_style, + }, + }, 'fieldorder' => [qw( recur_method cutoff_day ), FS::part_pkg::prorate_Mixin::fieldorder, - qw( datasrc db_username db_password query + qw( datasrc db_username db_password query query_style )], 'weight' => '58', ); sub price_info { my $self = shift; - my $str = $self->SUPER::price_info; + my $str = $self->SUPER::price_info(@_); $str .= " plus per-service charges" if $str; $str; } @@ -53,6 +68,7 @@ sub calc_recur { my $self = shift; my($cust_pkg, $sdate, $details, $param ) = @_; my $price = 0; + my $quantity; # can be overridden; if not we use the default my $dbh = DBI->connect( map { $self->option($_) } qw( datasrc db_username db_password ) @@ -67,11 +83,61 @@ sub calc_recur { ) { my $id = $cust_svc->svc_x->id; $sth->execute($id) or die $sth->errstr; - $price += $sth->fetchrow_arrayref->[0]; + + if ( $self->option('query_style') eq 'detailed' ) { + + while (my $row = $sth->fetchrow_hashref) { + if (exists $row->{amount}) { + if ( $row->{amount} eq '' ) { + # treat as zero + } elsif ( $row->{amount} =~ /^\d+(?:\.\d+)?$/ ) { + $price += $row->{amount}; + } else { + die "sql_external query returned non-numeric amount: $row->{amount}"; + } + } + if (defined $row->{quantity}) { + if ( $row->{quantity} eq '' ) { + # treat as zero + } elsif ( $row->{quantity} =~ /^\d+$/ ) { + $quantity += $row->{quantity}; + } else { + die "sql_external query returned non-integer quantity: $row->{quantity}"; + } + } + + my $detail = FS::cust_bill_pkg_detail->new; + foreach my $field (@detail_cols) { + if (exists $row->{$field}) { + $detail->set($field, $row->{$field}); + } + } + if (!$detail->get('detail')) { + die "sql_external query did not return detail description"; + # or make something up? + # or just don't insert the detail? + } + + push @$details, $detail; + } # while $row + + } else { + + # simple style: returns only a single value, which is the price + $price += $sth->fetchrow_arrayref->[0]; + + } + } + $price = sprintf('%.2f', $price); + + # XXX probably shouldn't allow package quantity > 1 on these packages. + if ($cust_pkg->quantity > 1) { + warn "sql_external package #".$cust_pkg->pkgnum." has quantity > 1\n"; } + $param->{'override_quantity'} = $quantity; $param->{'override_charges'} = $price; - $self->calc_recur_Common($cust_pkg,$sdate,$details,$param); + ($cust_pkg->quantity || 1) * $self->calc_recur_Common($cust_pkg,$sdate,$details,$param); } sub can_discount { 1; }