X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;ds=inline;f=FS%2FFS%2Fquotation_pkg.pm;h=5607b9c331a2137922a2586cd9ebba128c75c2be;hb=fd5d458eda666a60ec0cdf35e5cbdff438b4ed76;hp=107b2718867f6356d902ef7f17269847015faf72;hpb=e19085190e34fce90b15bd9ec0c8d98b4fc8cd9a;p=freeside.git diff --git a/FS/FS/quotation_pkg.pm b/FS/FS/quotation_pkg.pm index 107b27188..5607b9c33 100644 --- a/FS/FS/quotation_pkg.pm +++ b/FS/FS/quotation_pkg.pm @@ -7,6 +7,7 @@ use FS::part_pkg; use FS::cust_location; use FS::quotation; use FS::quotation_pkg_discount; #so its loaded when TemplateItem_Mixin needs it +use FS::quotation_pkg_detail; use List::Util qw(sum); =head1 NAME @@ -97,6 +98,7 @@ sub display_table { 'quotation_pkg'; } # # (for invoice display order) sub discount_table { 'quotation_pkg_discount'; } +sub detail_table { 'quotation_pkg_detail'; } =item insert @@ -112,6 +114,22 @@ sub insert { my $oldAutoCommit = $FS::UID::AutoCommit; local $FS::UID::AutoCommit = 0; + #false laziness w/cust_main::Packages::order_pkg + if ( $options{'locationnum'} and $options{'locationnum'} != -1 ) { + + $self->locationnum($options{'locationnum'}); + + } elsif ( $options{'cust_location'} ) { + + my $error = $options{'cust_location'}->find_or_insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "inserting cust_location (transaction rolled back): $error"; + } + $self->locationnum($options{'cust_location'}->locationnum); + + } + my $error = $self->SUPER::insert; if ( !$error and $self->discountnum ) { @@ -147,15 +165,21 @@ sub delete { my $oldAutoCommit = $FS::UID::AutoCommit; local $FS::UID::AutoCommit = 0; + my $error = $self->delete_details; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + foreach ($self->quotation_pkg_discount, $self->quotation_pkg_tax) { - my $error = $_->delete; + $error = $_->delete; if ( $error ) { $dbh->rollback if $oldAutoCommit; return $error . ' (deleting discount)'; } } - my $error = $self->SUPER::delete; + $error = $self->SUPER::delete; if ( $error ) { $dbh->rollback if $oldAutoCommit; return $error; @@ -195,6 +219,20 @@ sub check { || $self->ut_enum('waive_setup', [ '', 'Y'] ) ; + if ($self->locationnum eq '') { + # use the customer default + my $quotation = $self->quotation; + if ($quotation->custnum) { + $self->set('locationnum', $quotation->cust_main->ship_locationnum); + } elsif ($quotation->prospectnum) { + # use the first non-disabled location for that prospect + my $cust_location = qsearchs('cust_location', + { prospectnum => $quotation->prospectnum, + disabled => '' }); + $self->set('locationnum', $cust_location->locationnum) if $cust_location; + } # else the quotation is invalid + } + return $error if $error; $self->SUPER::check; @@ -220,25 +258,20 @@ on failure. sub estimate { my $self = shift; - my $part_pkg = $self->part_pkg; - my $quantity = $self->quantity || 1; - my ($unitsetup, $unitrecur); - # calculate base fees - if ( $self->waive_setup eq 'Y' || $self->{'_NO_SETUP_KLUDGE'} ) { - $unitsetup = '0.00'; - } else { - $unitsetup = $part_pkg->option('setup_fee',1) || '0.00'; # XXX 3.x only - } - if ( $self->{'_NO_RECUR_KLUDGE'} ) { - $unitrecur = '0.00'; - } else { - $unitrecur = $part_pkg->base_recur; - } - #XXX add-on packages + my( $unitsetup, $unitrecur ) = (0, 0); + foreach my $part_pkg ( $self->part_pkg->self_and_bill_linked ) { + + $unitsetup += $part_pkg->option('setup_fee',1) || '0' # 3.x only + unless $self->waive_setup eq 'Y' || $self->{'_NO_SETUP_KLUDGE'}; - $self->set('unitsetup', $unitsetup); - $self->set('unitrecur', $unitrecur); + $unitrecur += $part_pkg->base_recur + unless $self->{'_NO_RECUR_KLUDGE'}; + + } + + $self->set('unitsetup', sprintf('%.2f', $unitsetup) ); + $self->set('unitrecur', sprintf('%.2f', $unitrecur) ); my $error = $self->replace; return $error if $error; @@ -362,12 +395,102 @@ sub setup { * ($self->quantity || 1); } +sub setup_show_zero { + my $self = shift; + return $self->part_pkg->setup_show_zero; +} + sub recur { my $self = shift; ($self->unitrecur - sum(0, map { $_->recur_amount } $self->pkg_discount)) * ($self->quantity || 1); } +sub recur_show_zero { + my $self = shift; + return $self->part_pkg->recur_show_zero; +} + +=item delete_details + +Deletes all quotation_pkgs_details associated with this pkg (see L). + +=cut + +sub delete_details { + my $self = shift; + + my $oldAutoCommit = $FS::UID::AutoCommit; + local $FS::UID::AutoCommit = 0; + my $dbh = dbh; + + foreach my $detail ( qsearch('quotation_pkg_detail',{ 'quotationpkgnum' => $self->quotationpkgnum }) ) { + my $error = $detail->delete; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "error removing old detail: $error"; + } + } + + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + ''; + +} + +=item set_details PARAM + +Sets new quotation details for this package (see L), +removing existing details. + +Recognizes the following parameters: + +details - arrayref of strings, one for each new detail + +copy_on_order - if true, sets copy_on_order flag on new details + +If there is an error, returns the error, otherwise returns false. + +=cut + +sub set_details { + my $self = shift; + my %opt = @_; + + $opt{'details'} ||= []; + my @details = @{$opt{'details'}}; + + my $oldAutoCommit = $FS::UID::AutoCommit; + local $FS::UID::AutoCommit = 0; + my $dbh = dbh; + + my $error = $self->delete_details; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + foreach my $detail ( @details ) { + my $quotation_pkg_detail = new FS::quotation_pkg_detail { + 'quotationpkgnum' => $self->quotationpkgnum, + 'detail' => $detail, + 'copy_on_order' => $opt{'copy_on_order'} ? 'Y' : '', + }; + $error = $quotation_pkg_detail->insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "error adding new detail: $error"; + } + } + + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + ''; + +} + +sub details_header { + return (); +} + =item cust_bill_pkg_display [ type => TYPE ] =cut @@ -429,6 +552,12 @@ sub quotation { FS::quotation->by_key($self->quotationnum); } +sub quotation_pkg_detail { + my $self = shift; + sort { $a->detailnum <=> $b->detailnum } + qsearch('quotation_pkg_detail', { quotationpkgnum => $self->quotationpkgnum }); +} + sub quotation_pkg_discount { my $self = shift; qsearch('quotation_pkg_discount', { quotationpkgnum => $self->quotationpkgnum }); @@ -444,6 +573,24 @@ sub cust_location { $self->locationnum ? qsearchs('cust_location', { locationnum => $self->locationnum }) : ''; } + +sub _upgrade_data { + my $class = shift; + my @quotation_pkg_without_location = + qsearch( 'quotation_pkg', { locationnum => '' } ); + if (@quotation_pkg_without_location) { + warn "setting default location on quotation_pkg records\n"; + foreach my $quotation_pkg (@quotation_pkg_without_location) { + # check() will fix this + my $error = $quotation_pkg->replace; + if ($error) { + die "quotation #".$quotation_pkg->quotationnum.": $error\n"; + } + } + } + ''; +} + =back =head1 BUGS