1 package FS::o2m_Common;
4 use vars qw( $DEBUG $me );
6 use FS::Schema qw( dbdef );
7 use FS::Record qw( qsearch qsearchs dbh );
11 $me = '[FS::o2m_Common]';
15 FS::o2m_Common - Mixin class for tables with a related table
21 @ISA = qw( FS::o2m_Common FS::Record );
25 FS::o2m_Common is intended as a mixin class for classes which have a
32 =item process_o2m OPTION => VALUE, ...
36 table (required) - Table into which the records are inserted.
38 num_col (optional) - Column in table which links to the primary key of the base table. If not specified, it is assumed this has the same name.
40 params (required) - Hashref of keys and values, often passed as C<scalar($cgi->Vars)> from a form.
42 fields (required) - Arrayref of field names for each record in table. Pulled from params as "pkeyNN_field" where pkey is table's primary key and NN is the entry's numeric identifier.
46 #a little more false laziness w/m2m_Common.pm than m2_name_Common.pm
47 # still, far from the worse of it. at least we're a reuable mixin!
49 my( $self, %opt ) = @_;
51 my $self_pkey = $self->dbdef_table->primary_key;
52 my $link_sourcekey = $opt{'num_col'} || $self_pkey;
54 my $hashref = {}; #$opt{'hashref'} || {};
55 $hashref->{$link_sourcekey} = $self->$self_pkey();
57 my $table = $self->_load_table($opt{'table'});
58 my $table_pkey = dbdef->table($table)->primary_key;
60 # my $link_static = $opt{'link_static'} || {};
62 warn "$me processing o2m from ". $self->table. ".$link_sourcekey".
66 #if ( ref($opt{'params'}) eq 'ARRAY' ) {
67 # $opt{'params'} = { map { $_=>1 } @{$opt{'params'}} };
70 local $SIG{HUP} = 'IGNORE';
71 local $SIG{INT} = 'IGNORE';
72 local $SIG{QUIT} = 'IGNORE';
73 local $SIG{TERM} = 'IGNORE';
74 local $SIG{TSTP} = 'IGNORE';
75 local $SIG{PIPE} = 'IGNORE';
77 my $oldAutoCommit = $FS::UID::AutoCommit;
78 local $FS::UID::AutoCommit = 0;
81 my @fields = grep { /^$table_pkey\d+$/ }
82 keys %{ $opt{'params'} };
84 my %edits = map { $opt{'params'}->{$_} => $_ }
85 grep { $opt{'params'}->{$_} }
89 grep { ! $edits{$_->$table_pkey()} }
90 qsearch( $table, $hashref )
92 my $error = $del_obj->delete;
94 $dbh->rollback if $oldAutoCommit;
99 foreach my $pkey_value ( keys %edits ) {
100 my $old_obj = qsearchs( $table, { %$hashref, $table_pkey => $pkey_value } ),
101 my $add_param = $edits{$pkey_value};
102 my %hash = ( $table_pkey => $pkey_value,
103 map { $_ => $opt{'params'}->{$add_param."_$_"} }
106 #next unless grep { $_ =~ /\S/ } values %hash;
108 my $new_obj = "FS::$table"->new( { %$hashref, %hash } );
109 my $error = $new_obj->replace($old_obj);
111 $dbh->rollback if $oldAutoCommit;
116 foreach my $add_param ( grep { ! $opt{'params'}->{$_} } @fields ) {
118 my %hash = map { $_ => $opt{'params'}->{$add_param."_$_"} }
120 next unless grep { $_ =~ /\S/ } values %hash;
122 my $add_obj = "FS::$table"->new( { %$hashref, %hash } );
123 my $error = $add_obj->insert;
125 $dbh->rollback if $oldAutoCommit;
130 $dbh->commit or die $dbh->errstr if $oldAutoCommit;
135 my( $self, $table ) = @_;
136 eval "use FS::$table";