summaryrefslogtreecommitdiff
path: root/FS/FS/o2m_Common.pm
diff options
context:
space:
mode:
authorivan <ivan>2009-12-28 19:20:25 +0000
committerivan <ivan>2009-12-28 19:20:25 +0000
commit03ceab71dad1e5eb366865d304e5e459cc905ce4 (patch)
tree18b4532289a0237ae694b1ad5c033b25f448bd7c /FS/FS/o2m_Common.pm
parent5950a980cef4968ac59ca8041d2204e6d98e7a3d (diff)
beginning of prospect/CRM/contact work
Diffstat (limited to 'FS/FS/o2m_Common.pm')
-rw-r--r--FS/FS/o2m_Common.pm152
1 files changed, 152 insertions, 0 deletions
diff --git a/FS/FS/o2m_Common.pm b/FS/FS/o2m_Common.pm
new file mode 100644
index 0000000..0e03b52
--- /dev/null
+++ b/FS/FS/o2m_Common.pm
@@ -0,0 +1,152 @@
+package FS::o2m_Common;
+
+use strict;
+use vars qw( $DEBUG $me );
+use Carp;
+use FS::Schema qw( dbdef );
+use FS::Record qw( qsearch qsearchs dbh );
+
+$DEBUG = 0;
+
+$me = '[FS::o2m_Common]';
+
+=head1 NAME
+
+FS::o2m_Common - Mixin class for tables with a related table
+
+=head1 SYNOPSIS
+
+use FS::o2m_Common;
+
+@ISA = qw( FS::o2m_Common FS::Record );
+
+=head1 DESCRIPTION
+
+FS::o2m_Common is intended as a mixin class for classes which have a
+related table.
+
+=head1 METHODS
+
+=over 4
+
+=item process_o2m OPTION => VALUE, ...
+
+Available options:
+
+table (required) - Table into which the records are inserted.
+
+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.
+
+params (required) - Hashref of keys and values, often passed as C<scalar($cgi->Vars)> from a form.
+
+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.
+
+=cut
+
+#a little more false laziness w/m2m_Common.pm than m2_name_Common.pm
+# still, far from the worse of it. at least we're a reuable mixin!
+sub process_o2m {
+ my( $self, %opt ) = @_;
+
+ my $self_pkey = $self->dbdef_table->primary_key;
+ my $link_sourcekey = $opt{'num_col'} || $self_pkey;
+
+ my $hashref = {}; #$opt{'hashref'} || {};
+ $hashref->{$link_sourcekey} = $self->$self_pkey();
+
+ my $table = $self->_load_table($opt{'table'});
+ my $table_pkey = dbdef->table($table)->primary_key;
+
+# my $link_static = $opt{'link_static'} || {};
+
+ warn "$me processing o2m from ". $self->table. ".$link_sourcekey".
+ " to $table\n"
+ if $DEBUG;
+
+ #if ( ref($opt{'params'}) eq 'ARRAY' ) {
+ # $opt{'params'} = { map { $_=>1 } @{$opt{'params'}} };
+ #}
+
+ local $SIG{HUP} = 'IGNORE';
+ local $SIG{INT} = 'IGNORE';
+ local $SIG{QUIT} = 'IGNORE';
+ local $SIG{TERM} = 'IGNORE';
+ local $SIG{TSTP} = 'IGNORE';
+ local $SIG{PIPE} = 'IGNORE';
+
+ my $oldAutoCommit = $FS::UID::AutoCommit;
+ local $FS::UID::AutoCommit = 0;
+ my $dbh = dbh;
+
+ my @fields = grep { /^$table_pkey\d+$/ }
+ keys %{ $opt{'params'} };
+
+ my %edits = map { $opt{'params'}->{$_} => $_ }
+ grep { $opt{'params'}->{$_} }
+ @fields;
+
+ foreach my $del_obj (
+ grep { ! $edits{$_->$table_pkey()} }
+ qsearch( $table, $hashref )
+ ) {
+ my $error = $del_obj->delete;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+ }
+
+ foreach my $pkey_value ( keys %edits ) {
+ my $old_obj = qsearchs( $table, { %$hashref, $table_pkey => $pkey_value } ),
+ my $add_param = $edits{$pkey_value};
+ my %hash = ( $table_pkey => $pkey_value,
+ map { $_ => $opt{'params'}->{$add_param."_$_"} }
+ @{ $opt{'fields'} }
+ );
+ #next unless grep { $_ =~ /\S/ } values %hash;
+
+ my $new_obj = "FS::$table"->new( { %$hashref, %hash } );
+ my $error = $new_obj->replace($old_obj);
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+ }
+
+ foreach my $add_param ( grep { ! $opt{'params'}->{$_} } @fields ) {
+
+ my %hash = map { $_ => $opt{'params'}->{$add_param."_$_"} }
+ @{ $opt{'fields'} };
+ next unless grep { $_ =~ /\S/ } values %hash;
+
+ my $add_obj = "FS::$table"->new( { %$hashref, %hash } );
+ my $error = $add_obj->insert;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+ }
+
+ $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+ '';
+}
+
+sub _load_table {
+ my( $self, $table ) = @_;
+ eval "use FS::$table";
+ die $@ if $@;
+ $table;
+}
+
+=back
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<FS::Record>
+
+=cut
+
+1;
+