X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=FS%2FFS%2Fpart_pkg.pm;h=1db5a708c6e0974f922d47e0f7844e4290c5ba46;hp=58f70716d76b3a4353a80e9531de5b5feefd5c5b;hb=392d0c1164bf5d222826164195502906252ba2dd;hpb=d3ce5efd1ec0e1a715a154696e2b0aa86e51c27b diff --git a/FS/FS/part_pkg.pm b/FS/FS/part_pkg.pm index 58f70716d..1db5a708c 100644 --- a/FS/FS/part_pkg.pm +++ b/FS/FS/part_pkg.pm @@ -277,19 +277,20 @@ sub insert { } if ( $options{'part_pkg_vendor'} ) { - my($exportnum,$vendor_pkg_id); - my %options_part_pkg_vendor = $options{'part_pkg_vendor'}; - while(($exportnum,$vendor_pkg_id) = each %options_part_pkg_vendor){ - my $ppv = new FS::part_pkg_vendor( { - 'pkgpart' => $self->pkgpart, - 'exportnum' => $exportnum, - 'vendor_pkg_id' => $vendor_pkg_id, - } ); - my $error = $ppv->insert; - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return "Error inserting part_pkg_vendor record: $error"; - } + while ( my ($exportnum, $vendor_pkg_id) = + each %{ $options{part_pkg_vendor} } + ) + { + my $ppv = new FS::part_pkg_vendor( { + 'pkgpart' => $self->pkgpart, + 'exportnum' => $exportnum, + 'vendor_pkg_id' => $vendor_pkg_id, + } ); + my $error = $ppv->insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "Error inserting part_pkg_vendor record: $error"; + } } } @@ -456,48 +457,48 @@ sub replace { if ( $options->{'part_pkg_vendor'} ) { my($exportnum,$vendor_pkg_id); while ( ($exportnum,$vendor_pkg_id) - = each %{$options->{'part_pkg_vendor'}} ) { - my $noinsert = 0; - foreach my $part_pkg_vendor ( @part_pkg_vendor ) { - if($exportnum == $part_pkg_vendor->exportnum - && $vendor_pkg_id ne $part_pkg_vendor->vendor_pkg_id) { - $part_pkg_vendor->vendor_pkg_id($vendor_pkg_id); - my $error = $part_pkg_vendor->replace; - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return "Error replacing part_pkg_vendor record: $error"; - } - $noinsert = 1; - last; - } - elsif($exportnum == $part_pkg_vendor->exportnum - && $vendor_pkg_id eq $part_pkg_vendor->vendor_pkg_id) { - $noinsert = 1; - last; - } - } - unless ( $noinsert ) { - my $ppv = new FS::part_pkg_vendor( { - 'pkgpart' => $new->pkgpart, - 'exportnum' => $exportnum, - 'vendor_pkg_id' => $vendor_pkg_id, - } ); - my $error = $ppv->insert; - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return "Error inserting part_pkg_vendor record: $error"; - } - } - push @current_exportnum, $exportnum; + = each %{$options->{'part_pkg_vendor'}} ) { + my $noinsert = 0; + foreach my $part_pkg_vendor ( @part_pkg_vendor ) { + if($exportnum == $part_pkg_vendor->exportnum + && $vendor_pkg_id ne $part_pkg_vendor->vendor_pkg_id) { + $part_pkg_vendor->vendor_pkg_id($vendor_pkg_id); + my $error = $part_pkg_vendor->replace; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "Error replacing part_pkg_vendor record: $error"; + } + $noinsert = 1; + last; + } + elsif($exportnum == $part_pkg_vendor->exportnum + && $vendor_pkg_id eq $part_pkg_vendor->vendor_pkg_id) { + $noinsert = 1; + last; + } + } + unless ( $noinsert ) { + my $ppv = new FS::part_pkg_vendor( { + 'pkgpart' => $new->pkgpart, + 'exportnum' => $exportnum, + 'vendor_pkg_id' => $vendor_pkg_id, + } ); + my $error = $ppv->insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "Error inserting part_pkg_vendor record: $error"; + } + } + push @current_exportnum, $exportnum; } } foreach my $part_pkg_vendor ( @part_pkg_vendor ) { unless ( grep($_ eq $part_pkg_vendor->exportnum, @current_exportnum) ) { - my $error = $part_pkg_vendor->delete; - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return "Error deleting part_pkg_vendor record: $error"; - } + my $error = $part_pkg_vendor->delete; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "Error deleting part_pkg_vendor record: $error"; + } } } @@ -552,6 +553,8 @@ sub check { || $self->ut_enum('disabled', [ '', 'Y' ] ) || $self->ut_enum('custom', [ '', 'Y' ] ) || $self->ut_enum('no_auto', [ '', 'Y' ]) + || $self->ut_enum('recur_show_zero', [ '', 'Y' ]) + || $self->ut_enum('setup_show_zero', [ '', 'Y' ]) #|| $self->ut_moneyn('setup_cost') #|| $self->ut_moneyn('recur_cost') || $self->ut_floatn('setup_cost') @@ -605,9 +608,13 @@ sub pkg_comment { $pre. $self->pkg. ' - '. $self->custom_comment; } +sub price_info { # safety, in case a part_pkg hasn't defined price_info + ''; +} + sub custom_comment { my $self = shift; - ( $self->custom ? '(CUSTOM) ' : '' ). $self->comment; + ( $self->custom ? '(CUSTOM) ' : '' ). $self->comment . ' ' . $self->price_info; } =item pkg_class @@ -844,10 +851,7 @@ Returns true if this package is free. sub is_free { my $self = shift; - unless ( $self->plan ) { - $self->setup =~ /^\s*0+(\.0*)?\s*$/ - && $self->recur =~ /^\s*0+(\.0*)?\s*$/; - } elsif ( $self->can('is_free_options') ) { + if ( $self->can('is_free_options') ) { not grep { $_ !~ /^\s*0*(\.0*)?\s*$/ } map { $self->option($_) } $self->is_free_options; @@ -860,6 +864,8 @@ sub is_free { sub can_discount { 0; } +sub can_start_date { 1; } + sub freqs_href { # moved to FS::Misc to make this accessible to other packages # at initialization @@ -1060,6 +1066,10 @@ sub self_and_bill_linked { shift->_self_and_linked('bill', @_); } +sub self_and_svc_linked { + shift->_self_and_linked('svc', @_); +} + sub _self_and_linked { my( $self, $type, $hidden ) = @_; $hidden ||= ''; @@ -1274,38 +1284,11 @@ sub _rebless { $self; } -#fallbacks that eval the setup and recur fields, for backwards compat - -sub calc_setup { - my $self = shift; - warn 'no price plan class for '. $self->plan. ", eval-ing setup\n"; - $self->_calc_eval('setup', @_); -} - -sub calc_recur { - my $self = shift; - warn 'no price plan class for '. $self->plan. ", eval-ing recur\n"; - $self->_calc_eval('recur', @_); -} - -use vars qw( $sdate @details ); -sub _calc_eval { - #my( $self, $field, $cust_pkg ) = @_; - my( $self, $field, $cust_pkg, $sdateref, $detailsref ) = @_; - *sdate = $sdateref; - *details = $detailsref; - $self->$field() =~ /^(.*)$/ - or die "Illegal $field (pkgpart ". $self->pkgpart. '): '. - $self->$field(). "\n"; - my $prog = $1; - return 0 if $prog =~ /^\s*$/; - my $value = eval $prog; - die $@ if $@; - $value; -} +#fatal fallbacks +sub calc_setup { die 'no calc_setup for '. shift->plan. "\n"; } +sub calc_recur { die 'no calc_recur for '. shift->plan. "\n"; } #fallback that return 0 for old legacy packages with no plan - sub calc_remain { 0; } sub calc_cancel { 0; } sub calc_units { 0; } @@ -1313,6 +1296,9 @@ sub calc_units { 0; } #fallback for everything except bulk.pm sub hide_svc_detail { 0; } +#fallback for packages that can't/won't summarize usage +sub sum_usage { 0; } + =item recur_cost_permonth CUST_PKG recur_cost divided by freq (only supported for monthly and longer frequencies) @@ -1459,6 +1445,59 @@ sub _upgrade_data { # class method die $error if $error; } + my @part_pkg_option = qsearch('part_pkg_option', + { 'optionname' => 'unused_credit', + 'optionvalue' => 1, + }); + foreach my $old_opt (@part_pkg_option) { + my $pkgpart = $old_opt->pkgpart; + my $error = $old_opt->delete; + die $error if $error; + + foreach (qw(unused_credit_cancel unused_credit_change)) { + my $new_opt = new FS::part_pkg_option { + 'pkgpart' => $pkgpart, + 'optionname' => $_, + 'optionvalue' => 1, + }; + $error = $new_opt->insert; + die $error if $error; + } + } + + # migrate use_disposition_taqua and use_disposition to disposition_in + @part_pkg_option = qsearch('part_pkg_option', + { 'optionname' => { op => 'LIKE', + value => 'use_disposition%', + }, + 'optionvalue' => 1, + }); + my %newopts = map { $_->pkgpart => $_ } + qsearch('part_pkg_option', { 'optionname' => 'disposition_in', } ); + foreach my $old_opt (@part_pkg_option) { + my $pkgpart = $old_opt->pkgpart; + my $newval = $old_opt->optionname eq 'use_disposition_taqua' ? '100' + : 'ANSWERED'; + my $error = $old_opt->delete; + die $error if $error; + + if ( exists($newopts{$pkgpart}) ) { + my $opt = $newopts{$pkgpart}; + $opt->optionvalue($opt->optionvalue.",$newval"); + $error = $opt->replace; + die $error if $error; + } else { + my $new_opt = new FS::part_pkg_option { + 'pkgpart' => $pkgpart, + 'optionname' => 'disposition_in', + 'optionvalue' => $newval, + }; + $error = $new_opt->insert; + die $error if $error; + $newopts{$pkgpart} = $new_opt; + } + } + } =item curuser_pkgs_sql @@ -1571,6 +1610,10 @@ foreach my $name (keys(%info)) { my $parents = $info{$name}->{'inherit_fields'} || []; my (%fields, %field_exists, @fieldorder); foreach my $parent ($name, @$parents) { + if ( !exists($info{$parent}) ) { + warn "$name tried to inherit from nonexistent '$parent'\n"; + next; + } %fields = ( # avoid replacing existing fields %{ $info{$parent}->{'fields'} || {} }, %fields @@ -1580,7 +1623,8 @@ foreach my $name (keys(%info)) { next if $field_exists{$_}; $field_exists{$_} = 1; # allow inheritors to remove inherited fields from the fieldorder - push @fieldorder, $_ if !exists($fields{$_}->{'disabled'}); + push @fieldorder, $_ if !exists($fields{$_}) or + !exists($fields{$_}->{'disabled'}); } } $plans{$name}->{'fields'} = \%fields;