This commit was manufactured by cvs2svn to create tag 'freeside_2_1_1'.
[freeside.git] / FS / FS / svc_Common.pm
index ee270ca..71290f4 100644 (file)
@@ -401,7 +401,7 @@ sub replace {
   local $FS::UID::AutoCommit = 0;
   my $dbh = dbh;
 
-  my $error = $new->set_auto_inventory;
+  my $error = $new->set_auto_inventory($old);
   if ( $error ) {
     $dbh->rollback if $oldAutoCommit;
     return $error;
@@ -685,13 +685,16 @@ sub pbx_select_hash {
 
 =item set_auto_inventory
 
-Sets any fields which auto-populate from inventory (see L<FS::part_svc>).
+Sets any fields which auto-populate from inventory (see L<FS::part_svc>), and
+also check any manually populated inventory fields.
+
 If there is an error, returns the error, otherwise returns false.
 
 =cut
 
 sub set_auto_inventory {
   my $self = shift;
+  my $old = @_ ? shift : '';
 
   my $error =
     $self->ut_numbern('svcnum')
@@ -715,39 +718,76 @@ sub set_auto_inventory {
   #set default/fixed/whatever fields from part_svc
   my $table = $self->table;
   foreach my $field ( grep { $_ ne 'svcnum' } $self->fields ) {
+
     my $part_svc_column = $part_svc->part_svc_column($field);
-    if ( $part_svc_column->columnflag eq 'A' && $self->$field() eq '' ) {
-
-      my $classnum = $part_svc_column->columnvalue;
-      my $inventory_item = qsearchs({
-        'table'     => 'inventory_item',
-        'hashref'   => { 'classnum' => $classnum, 
-                         'svcnum'   => '',
-                       },
-        'extra_sql' => 'LIMIT 1 FOR UPDATE',
-      });
+    my $columnflag = $part_svc_column->columnflag;
+    next unless $columnflag =~ /^[AM]$/;
 
-      unless ( $inventory_item ) {
-        $dbh->rollback if $oldAutoCommit;
-        my $inventory_class =
-          qsearchs('inventory_class', { 'classnum' => $classnum } );
-        return "Can't find inventory_class.classnum $classnum"
-          unless $inventory_class;
-        return "Out of ". $inventory_class->classname. "s\n"; #Lingua:: BS
-                                                              #for pluralizing
-      }
+    next if $columnflag eq 'A' && $self->$field() ne '';
 
-      $inventory_item->svcnum( $self->svcnum );
-      my $ierror = $inventory_item->replace();
-      if ( $ierror ) {
-        $dbh->rollback if $oldAutoCommit;
-        return "Error provisioning inventory: $ierror";
-        
-      }
+    my $classnum = $part_svc_column->columnvalue;
+    my %hash = ( 'classnum' => $classnum );
+
+    if ( $columnflag eq 'A' && $self->$field() eq '' ) {
+      $hash{'svcnum'} = '';
+    } elsif ( $columnflag eq 'M' ) {
+      return "Select inventory item for $field" unless $self->getfield($field);
+      $hash{'item'} = $self->getfield($field);
+    }
 
-      $self->setfield( $field, $inventory_item->item );
+    my $agentnums_sql = $FS::CurrentUser::CurrentUser->agentnums_sql(
+      'null'  => 1,
+      'table' => 'inventory_item',
+    );
 
+    my $inventory_item = qsearchs({
+      'table'     => 'inventory_item',
+      'hashref'   => \%hash,
+      'extra_sql' => "AND $agentnums_sql",
+      'order_by'  => 'ORDER BY ( agentnum IS NULL ) '. #agent inventory first
+                     ' LIMIT 1 FOR UPDATE',
+    });
+
+    unless ( $inventory_item ) {
+      $dbh->rollback if $oldAutoCommit;
+      my $inventory_class =
+        qsearchs('inventory_class', { 'classnum' => $classnum } );
+      return "Can't find inventory_class.classnum $classnum"
+        unless $inventory_class;
+      return "Out of ". $inventory_class->classname. "s\n"; #Lingua:: BS
+                                                            #for pluralizing
     }
+
+    next if $columnflag eq 'M' && $inventory_item->svcnum == $self->svcnum;
+
+    $self->setfield( $field, $inventory_item->item );
+      #if $columnflag eq 'A' && $self->$field() eq '';
+
+    $inventory_item->svcnum( $self->svcnum );
+    my $ierror = $inventory_item->replace();
+    if ( $ierror ) {
+      $dbh->rollback if $oldAutoCommit;
+      return "Error provisioning inventory: $ierror";
+    }
+
+    if ( $old && $old->$field() && $old->$field() ne $self->$field() ) {
+      my $old_inv = qsearchs({
+        'table'   => 'inventory_item',
+        'hashref' => { 'classnum' => $classnum,
+                       'svcnum'   => $old->svcnum,
+                       'item'     => $old->$field(),
+                     },
+      });
+      if ( $old_inv ) {
+        $old_inv->svcnum('');
+        my $oerror = $old_inv->replace;
+        if ( $oerror ) {
+          $dbh->rollback if $oldAutoCommit;
+          return "Error unprovisioning inventory: $oerror";
+        }
+      }
+    }
+
   }
 
  $dbh->commit or die $dbh->errstr if $oldAutoCommit;