X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fcust_svc.pm;h=8fc929f29c6ce7c983311c3380489a9f66b1db19;hb=fa978560e3b0473728ebf2fb32625765465c230a;hp=7bf41ee5d1a73b69c16443e9051856c426d4a407;hpb=32072dbf59a054529f5304574c0f56f9567d14d0;p=freeside.git diff --git a/FS/FS/cust_svc.pm b/FS/FS/cust_svc.pm index 7bf41ee5d..8fc929f29 100644 --- a/FS/FS/cust_svc.pm +++ b/FS/FS/cust_svc.pm @@ -5,6 +5,7 @@ use strict; use vars qw( $DEBUG $me $ignore_quantity $conf $ticket_system ); use Carp; #use Scalar::Util qw( blessed ); +use List::Util qw( max ); use FS::Conf; use FS::Record qw( qsearch qsearchs dbh str2time_sql ); use FS::part_pkg; @@ -321,14 +322,24 @@ sub replace { my $error = $new->svc_x->export('pkg_change', $new->cust_pkg, $old->cust_pkg, ); + if ( $error ) { $dbh->rollback if $oldAutoCommit; return $error if $error; } - } + } # if pkgnum is changing #my $error = $new->SUPER::replace($old, @_); my $error = $new->SUPER::replace($old); + + #trigger a relocate export on location changes + if ( $new->cust_pkg->locationnum != $old->cust_pkg->locationnum ) { + $error ||= $new->svc_x->export('relocate', + $new->cust_pkg->cust_location, + $old->cust_pkg->cust_location, + ); + } + if ( $error ) { $dbh->rollback if $oldAutoCommit; return $error if $error; @@ -363,15 +374,44 @@ sub check { return "Unknown svcpart" unless $part_svc; if ( $self->pkgnum && ! $ignore_quantity ) { - my $cust_pkg = qsearchs( 'cust_pkg', { 'pkgnum' => $self->pkgnum } ); - return "Unknown pkgnum" unless $cust_pkg; - ($part_svc) = grep { $_->svcpart == $self->svcpart } $cust_pkg->part_svc; - return "No svcpart ". $self->svcpart. - " services in pkgpart ". $cust_pkg->pkgpart - unless $part_svc || $ignore_quantity; - return "Already ". $part_svc->get('num_cust_svc'). " ". $part_svc->svc. + + #slightly inefficient since ->pkg_svc will also look it up, but fixing + # a much larger perf problem and have bigger fish to fry + my $cust_pkg = $self->cust_pkg; + + my $pkg_svc = $self->pkg_svc + || new FS::pkg_svc { 'svcpart' => $self->svcpart, + 'pkgpart' => $cust_pkg->pkgpart, + 'quantity' => 0, + }; + + #service add-ons, kinda false laziness/reimplementation of part_pkg->pkg_svc + foreach my $part_pkg_link ( $cust_pkg->part_pkg->svc_part_pkg_link ) { + my $addon_pkg_svc = qsearchs('pkg_svc', { + pkgpart => $part_pkg_link->dst_pkgpart, + svcpart => $self->svcpart, + }); + $pkg_svc->quantity( $pkg_svc->quantity + $addon_pkg_svc->quantity ) + if $addon_pkg_svc; + } + + #better error message? UI shouldn't get here + return "No svcpart ". $self->svcpart. + " services in pkgpart ". $cust_pkg->pkgpart + unless $pkg_svc->quantity > 0; + + my $num_cust_svc = $cust_pkg->num_cust_svc( $self->svcpart ); + + #false laziness w/cust_pkg->part_svc + my $num_avail = max( 0, ($cust_pkg->quantity || 1) * $pkg_svc->quantity + - $num_cust_svc + ); + + #better error message? again, UI shouldn't get here + return "Already $num_cust_svc ". $pkg_svc->part_svc->svc. " services for pkgnum ". $self->pkgnum - if !$ignore_quantity && $part_svc->get('num_avail') <= 0 ; + if $num_avail <= 0; + } $self->SUPER::check;