From: cvs2git Date: Tue, 15 Jul 2003 11:23:22 +0000 (+0000) Subject: This commit was manufactured by cvs2svn to create tag 'freeside_1_5_0pre3'. X-Git-Tag: freeside_1_5_0pre3 X-Git-Url: http://git.freeside.biz/gitweb/?a=commitdiff_plain;h=refs%2Ftags%2Ffreeside_1_5_0pre3;hp=a2ef3ae885f2bccc0828836678c7e5901241d88d;p=freeside.git This commit was manufactured by cvs2svn to create tag 'freeside_1_5_0pre3'. --- diff --git a/FS/FS/Misc.pm b/FS/FS/Misc.pm index efad2dfd6..56dc72e36 100644 --- a/FS/FS/Misc.pm +++ b/FS/FS/Misc.pm @@ -54,7 +54,7 @@ FS::UID->install_callback( sub { } ); sub send_email { - my(%options) = @_; + my(%options) = shift; $ENV{MAILADDRESS} = $options{'from'}; my $to = ref($options{to}) ? join(', ', @{ $options{to} } ) : $options{to}; @@ -77,16 +77,9 @@ sub send_email { my $smtpmachine = $conf->config('smtpmachine'); $!=0; - - my $rv = $message->smtpsend( 'Host' => $smtpmachine ) - or $message->smtpsend( Host => $smtpmachine, Debug => 1 ); - - if ($rv) { #smtpsend returns a list of addresses, not true/false - return ''; - } else { - return "can't send email to $to via server $smtpmachine with SMTP: $!"; - } - + $message->smtpsend( 'Host' => $smtpmachine ) + or $message->smtpsend( Host => $smtpmachine, Debug => 1 ) + or return "can't send email to $to via server $smtpmachine with SMTP: $!"; } =head1 BUGS diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm index a423c5518..9f20603bd 100644 --- a/FS/FS/cust_pkg.pm +++ b/FS/FS/cust_pkg.pm @@ -605,61 +605,6 @@ sub attribute_since_sqlradacct { } -=item transfer DEST_PKGNUM - -Transfers as many services as possible from this package to another package. -The destination package must already exist. Services are moved only if -the destination allows services with the correct I (not svcdb). -Any services that can't be moved remain in the original package. - -Returns an error, if there is one; otherwise, returns the number of services -that couldn't be moved. - -=cut - -sub transfer { - my ($self, $dest_pkgnum) = @_; - - my $remaining = 0; - my $dest; - my %target; - my $pkg_svc; - - if (ref ($dest_pkgnum) eq 'FS::cust_pkg') { - $dest = $dest_pkgnum; - $dest_pkgnum = $dest->pkgnum; - } else { - $dest = qsearchs('cust_pkg', { pkgnum => $dest_pkgnum }); - } - - return ('Package does not exist: '.$dest_pkgnum) unless $dest; - - foreach $pkg_svc (qsearch('pkg_svc', { pkgpart => $dest->pkgpart })) { - $target{$pkg_svc->svcpart} = $pkg_svc->quantity; - } - - my $cust_svc; - - foreach $cust_svc ($dest->cust_svc) { - $target{$cust_svc->svcpart}--; - } - - foreach $cust_svc ($self->cust_svc) { - if($target{$cust_svc->svcpart} > 0) { - $target{$cust_svc->svcpart}--; - my $new = new FS::cust_svc { - svcnum => $cust_svc->svcnum, - svcpart => $cust_svc->svcpart, - pkgnum => $dest_pkgnum }; - my $error = $new->replace($cust_svc); - return $error if $error; - } else { - $remaining++ - } - } - return $remaining; -} - =back =head1 SUBROUTINES @@ -686,62 +631,156 @@ newly-created cust_pkg objects. =cut sub order { + my($custnum, $pkgparts, $remove_pkgnums, $return_cust_pkg) = @_; + $remove_pkgnums = [] unless defined($remove_pkgnums); - # Rewritten to make use of the transfer() method, and in general - # to not suck so badly. - - my ($custnum, $pkgparts, $remove_pkgnum, $return_cust_pkg) = @_; - - # Transactionize this whole mess my $oldAutoCommit = $FS::UID::AutoCommit; local $FS::UID::AutoCommit = 0; my $dbh = dbh; - my $error; - my $cust_main = qsearchs('cust_main', { custnum => $custnum }); - return "Customer not found: $custnum" unless $cust_main; - - # Create the new packages. - my $cust_pkg; - foreach (@$pkgparts) { - $cust_pkg = new FS::cust_pkg { custnum => $custnum, - pkgpart => $_ }; - $error = $cust_pkg->insert; - if ($error) { + # generate %part_pkg + # $part_pkg{$pkgpart} is true iff $custnum may purchase $pkgpart + # + my($cust_main)=qsearchs('cust_main',{'custnum'=>$custnum}); + my($agent)=qsearchs('agent',{'agentnum'=> $cust_main->agentnum }); + my %part_pkg = %{ $agent->pkgpart_hashref }; + + my(%svcnum); + # generate %svcnum + # for those packages being removed: + #@{ $svcnum{$svcpart} } goes from a svcpart to a list of FS::cust_svc objects + my($pkgnum); + foreach $pkgnum ( @{$remove_pkgnums} ) { + foreach my $cust_svc (qsearch('cust_svc',{'pkgnum'=>$pkgnum})) { + push @{ $svcnum{$cust_svc->getfield('svcpart')} }, $cust_svc; + } + } + + my @cust_svc; + #generate @cust_svc + # for those packages the customer is purchasing: + # @{$pkgparts} is a list of said packages, by pkgpart + # @cust_svc is a corresponding list of lists of FS::Record objects + foreach my $pkgpart ( @{$pkgparts} ) { + unless ( $part_pkg{$pkgpart} ) { $dbh->rollback if $oldAutoCommit; - return $error; + return "Customer not permitted to purchase pkgpart $pkgpart!"; } - push @$return_cust_pkg, $cust_pkg; + push @cust_svc, [ + map { + ( $svcnum{$_} && @{ $svcnum{$_} } ) ? shift @{ $svcnum{$_} } : (); + } map { $_->svcpart } + qsearch('pkg_svc', { pkgpart => $pkgpart, + quantity => { op=>'>', value=>'0', } } ) + ]; } - # $return_cust_pkg now contains refs to all of the newly - # created packages. - - # Transfer services and cancel old packages. - foreach my $old_pkgnum (@$remove_pkgnum) { - my $old_pkg = qsearchs ('cust_pkg', { pkgnum => $old_pkgnum }); - foreach my $new_pkg (@$return_cust_pkg) { - $error = $old_pkg->transfer($new_pkg); - if ($error and $error == 0) { - # $old_pkg->transfer failed. - $dbh->rollback if $oldAutoCommit; - return $error; + + #special-case until this can be handled better + # move services to new svcparts - even if the svcparts don't match (svcdb + # needs to...) + # looks like they're moved in no particular order, ewwwwwwww + # and looks like just one of each svcpart can be moved... o well + + #start with still-leftover services + #foreach my $svcpart ( grep { scalar(@{ $svcnum{$_} }) } keys %svcnum ) { + foreach my $svcpart ( keys %svcnum ) { + next unless @{ $svcnum{$svcpart} }; + + my $svcdb = $svcnum{$svcpart}->[0]->part_svc->svcdb; + + #find an empty place to put one + my $i = 0; + foreach my $pkgpart ( @{$pkgparts} ) { + my @pkg_svc = + qsearch('pkg_svc', { pkgpart => $pkgpart, + quantity => { op=>'>', value=>'0', } } ); + #my @pkg_svc = + # grep { $_->quantity > 0 } qsearch('pkg_svc', { pkgpart=>$pkgpart } ); + if ( ! @{$cust_svc[$i]} #find an empty place to put them with + && grep { $svcdb eq $_->part_svc->svcdb } #with appropriate svcdb + @pkg_svc + ) { + my $new_svcpart = + ( grep { $svcdb eq $_->part_svc->svcdb } @pkg_svc )[0]->svcpart; + my $cust_svc = shift @{$svcnum{$svcpart}}; + $cust_svc->svcpart($new_svcpart); + #warn "changing from $svcpart to $new_svcpart!!!\n"; + $cust_svc[$i] = [ $cust_svc ]; } + $i++; } - if ($error > 0) { - # Transfers were successful, but we went through all of the - # new packages and still had services left on the old package. - # We can't cancel the package under the circumstances, so abort. + + } + + #check for leftover services + foreach (keys %svcnum) { + next unless @{ $svcnum{$_} }; + $dbh->rollback if $oldAutoCommit; + return "Leftover services, svcpart $_: svcnum ". + join(', ', map { $_->svcnum } @{ $svcnum{$_} } ); + } + + #no leftover services, let's make changes. + + local $SIG{HUP} = 'IGNORE'; + local $SIG{INT} = 'IGNORE'; + local $SIG{QUIT} = 'IGNORE'; + local $SIG{TERM} = 'IGNORE'; + local $SIG{TSTP} = 'IGNORE'; + local $SIG{PIPE} = 'IGNORE'; + + #first cancel old packages + foreach my $pkgnum ( @{$remove_pkgnums} ) { + my($old) = qsearchs('cust_pkg',{'pkgnum'=>$pkgnum}); + unless ( $old ) { $dbh->rollback if $oldAutoCommit; - return "Unable to transfer all services from package ".$old_pkg->pkgnum; + return "Package $pkgnum not found to remove!"; } - $error = $old_pkg->cancel; - if ($error) { - $dbh->rollback; - return $error; + my(%hash) = $old->hash; + $hash{'cancel'}=time; + my($new) = new FS::cust_pkg ( \%hash ); + my($error)=$new->replace($old); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "Couldn't update package $pkgnum: $error"; } } + + #now add new packages, changing cust_svc records if necessary + my $pkgpart; + while ($pkgpart=shift @{$pkgparts} ) { + + my $new = new FS::cust_pkg { + 'custnum' => $custnum, + 'pkgpart' => $pkgpart, + }; + my $error = $new->insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "Couldn't insert new cust_pkg record: $error"; + } + push @{$return_cust_pkg}, $new if $return_cust_pkg; + my $pkgnum = $new->pkgnum; + + foreach my $cust_svc ( @{ shift @cust_svc } ) { + my(%hash) = $cust_svc->hash; + $hash{'pkgnum'}=$pkgnum; + my $new = new FS::cust_svc ( \%hash ); + + #avoid Record diffing missing changed svcpart field from above. + my $old = qsearchs('cust_svc', { 'svcnum' => $cust_svc->svcnum } ); + + my $error = $new->replace($old); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "Couldn't link old service to new package: $error"; + } + } + } + $dbh->commit or die $dbh->errstr if $oldAutoCommit; - ''; + + ''; #no errors } =back