X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fcust_pkg.pm;h=aed99e51d22f580749725d014b096fe2099165f3;hb=ef5eceda8446cb44a5c5e2ad0d8ff979b9eb7bd8;hp=6899fa4cbaeebec45b4c77863b3eefe2e2086b0f;hpb=01629c3c934f1f6fd2ab9de5f7638f671fd59791;p=freeside.git diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm index 6899fa4cb..aed99e51d 100644 --- a/FS/FS/cust_pkg.pm +++ b/FS/FS/cust_pkg.pm @@ -10,7 +10,7 @@ use List::Util qw(max); use Tie::IxHash; use Time::Local qw( timelocal timelocal_nocheck ); use MIME::Entity; -use FS::UID qw( getotaker dbh ); +use FS::UID qw( getotaker dbh driver_name ); use FS::Misc qw( send_email ); use FS::Record qw( qsearch qsearchs fields ); use FS::CurrentUser; @@ -970,21 +970,25 @@ sub uncancel { } my $svc_error = $svc_x->insert; - if ( $svc_error && $options{svc_fatal} ) { - $dbh->rollback if $oldAutoCommit; - return $svc_error; - } else { - my $cust_svc = qsearchs('cust_svc', { 'svcnum' => $svc_x->svcnum }); - if ( $cust_svc ) { - my $cs_error = $cust_svc->delete; - if ( $cs_error ) { - $dbh->rollback if $oldAutoCommit; - return $cs_error; + if ( $svc_error ) { + if ( $options{svc_fatal} ) { + $dbh->rollback if $oldAutoCommit; + return $svc_error; + } else { + push @svc_errors, $svc_error; + # is this necessary? svc_Common::insert already deletes the + # cust_svc if inserting svc_x fails. + my $cust_svc = qsearchs('cust_svc', { 'svcnum' => $svc_x->svcnum }); + if ( $cust_svc ) { + my $cs_error = $cust_svc->delete; + if ( $cs_error ) { + $dbh->rollback if $oldAutoCommit; + return $cs_error; + } } - } - } - push @svc_errors, $svc_error if $svc_error; - } + } # svc_fatal + } # svc_error + } #foreach $h_cust_svc #these are pretty rare, but should handle them # - dsl_device (mac addresses) @@ -1189,8 +1193,13 @@ sub suspend { $hash{'resume'} = $resume_date; } + $options{options} ||= {}; + my $new = new FS::cust_pkg ( \%hash ); - $error = $new->replace( $self, options => { $self->options } ); + $error = $new->replace( $self, options => { $self->options, + %{ $options{options} }, + } + ); if ( $error ) { $dbh->rollback if $oldAutoCommit; return $error; @@ -2204,11 +2213,14 @@ field, I, which specifies the number of available services. sub available_part_svc { my $self = shift; + + my $pkg_quantity = $self->quantity || 1; + grep { $_->num_avail > 0 } map { my $part_svc = $_->part_svc; $part_svc->{'Hash'}{'num_avail'} = #evil encapsulation-breaking - $_->quantity - $self->num_cust_svc($_->svcpart); + $pkg_quantity * $_->quantity - $self->num_cust_svc($_->svcpart); # more evil encapsulation breakage if($part_svc->{'Hash'}{'num_avail'} > 0) { @@ -2250,6 +2262,8 @@ sub part_svc { my $self = shift; my %opt = @_; + my $pkg_quantity = $self->quantity || 1; + #XXX some sort of sort order besides numeric by svcpart... my @part_svc = sort { $a->svcpart <=> $b->svcpart } map { my $pkg_svc = $_; @@ -2257,7 +2271,7 @@ sub part_svc { my $num_cust_svc = $self->num_cust_svc($part_svc->svcpart); $part_svc->{'Hash'}{'num_cust_svc'} = $num_cust_svc; #more evil $part_svc->{'Hash'}{'num_avail'} = - max( 0, $pkg_svc->quantity - $num_cust_svc ); + max( 0, $pkg_quantity * $pkg_svc->quantity - $num_cust_svc ); $part_svc->{'Hash'}{'cust_pkg_svc'} = $num_cust_svc ? [ $self->cust_svc($part_svc->svcpart) ] : [] unless exists($opt{summarize_size}) && $opt{summarize_size} > 0 @@ -2695,7 +2709,7 @@ sub seconds_since_sqlradacct { grep { my $part_svc = $_->part_svc; $part_svc->svcdb eq 'svc_acct' - && scalar($part_svc->part_export('sqlradius')); + && scalar($part_svc->part_export_usage); } $self->cust_svc ) { $seconds += $cust_svc->seconds_since_sqlradacct($start, $end); @@ -2727,7 +2741,7 @@ sub attribute_since_sqlradacct { grep { my $part_svc = $_->part_svc; $part_svc->svcdb eq 'svc_acct' - && scalar($part_svc->part_export('sqlradius')); + && scalar($part_svc->part_export_usage); } $self->cust_svc ) { $sum += $cust_svc->attribute_since_sqlradacct($start, $end, $attrib); @@ -3585,20 +3599,40 @@ sub search { 'LEFT JOIN part_pkg USING ( pkgpart ) '. 'LEFT JOIN pkg_class ON ( part_pkg.classnum = pkg_class.classnum ) '; - my $count_query = "SELECT COUNT(*) FROM cust_pkg $addl_from $extra_sql"; + my $select; + my $count_query; + if ( $params->{'select_zip5'} ) { + my $zip = 'cust_location.zip'; + + $select = "DISTINCT substr($zip,1,5) as zip"; + $orderby = "ORDER BY substr($zip,1,5)"; + $addl_from .= 'LEFT JOIN cust_location ON ( + cust_location.locationnum = COALESCE( + cust_pkg.locationnum, + cust_main.ship_locationnum, + cust_main.bill_locationnum + ) + )'; + $count_query = "SELECT COUNT( DISTINCT substr($zip,1,5) )"; + } else { + $select = join(', ', + 'cust_pkg.*', + ( map "part_pkg.$_", qw( pkg freq ) ), + 'pkg_class.classname', + 'cust_main.custnum AS cust_main_custnum', + FS::UI::Web::cust_sql_fields( + $params->{'cust_fields'} + ), + ); + $count_query = 'SELECT COUNT(*)'; + } + + $count_query .= " FROM cust_pkg $addl_from $extra_sql"; my $sql_query = { 'table' => 'cust_pkg', 'hashref' => {}, - 'select' => join(', ', - 'cust_pkg.*', - ( map "part_pkg.$_", qw( pkg freq ) ), - 'pkg_class.classname', - 'cust_main.custnum AS cust_main_custnum', - FS::UI::Web::cust_sql_fields( - $params->{'cust_fields'} - ), - ), + 'select' => $select, 'extra_sql' => $extra_sql, 'order_by' => $orderby, 'addl_from' => $addl_from, @@ -3741,10 +3775,12 @@ sub _location_sql_where { my $or_empty_county = " OR ( ? = '' AND $table.${prefix}county IS NULL )"; my $or_empty_state = " OR ( ? = '' AND $table.${prefix}state IS NULL )"; + my $text = (driver_name =~ /^mysql/i) ? 'char' : 'text'; + # ( $table.${prefix}city = ? $or_empty_city $ornull ) " - ( $table.district = ? OR ? = '' OR CAST(? AS text) IS NULL ) - AND ( $table.${prefix}city = ? OR ? = '' OR CAST(? AS text) IS NULL ) + ( $table.district = ? OR ? = '' OR CAST(? AS $text) IS NULL ) + AND ( $table.${prefix}city = ? OR ? = '' OR CAST(? AS $text) IS NULL ) AND ( $table.${prefix}county = ? $or_empty_county $ornull ) AND ( $table.${prefix}state = ? $or_empty_state $ornull ) AND $table.${prefix}country = ?