X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fpart_export.pm;h=a43c3844ef2111d74a1989143528790a93b9b42d;hb=0b65ce59c7d2ee712389c27954382274ddf718a5;hp=67371bc3b534b6b0fe27c511fd504cddff259a50;hpb=b03df92e48df653460cb8b6034a06dd1de6f4095;p=freeside.git diff --git a/FS/FS/part_export.pm b/FS/FS/part_export.pm index 67371bc3b..a43c3844e 100644 --- a/FS/FS/part_export.pm +++ b/FS/FS/part_export.pm @@ -2,8 +2,9 @@ package FS::part_export; use strict; use vars qw( @ISA ); -use FS::Record qw( qsearch qsearchs ); +use FS::Record qw( qsearch qsearchs dbh ); use FS::part_svc; +use FS::part_export_option; @ISA = qw(FS::Record); @@ -18,7 +19,10 @@ FS::part_export - Object methods for part_export records $record = new FS::part_export \%hash; $record = new FS::part_export { 'column' => 'value' }; - $error = $record->insert; + ($new_record, $options) = $template_recored->clone( $svcpart ); + + $error = $record->insert( { 'option' => 'value' } ); + $error = $record->insert( \%options ); $error = $new_record->replace($old_record); @@ -34,7 +38,7 @@ fields are currently supported: =over 4 -=item eventpart - primary key +=item exportnum - primary key =item svcpart - Service definition (see L) to which this export applies @@ -63,14 +67,77 @@ points to. You can ask the object for a copy with the I method. sub table { 'part_export'; } -=item insert +=item clone SVCPART + +An alternate constructor. Creates a new export by duplicating an existing +export. The given svcpart is assigned to the new export. + +Returns a list consisting of the new export object and a hashref of options. + +=cut + +sub clone { + my $self = shift; + my $class = ref($self); + my %hash = $self->hash; + $hash{'exportnum'} = ''; + $hash{'svcpart'} = shift; + ( $class->new( \%hash ), + { map { $_->optionname => $_->optionvalue } + qsearch('part_export_option', { 'exportnum' => $self->exportnum } ) + } + ); +} + +=item insert HASHREF Adds this record to the database. If there is an error, returns the error, otherwise returns false. +If a hash reference of options is supplied, part_export_option records are +created (see L). + =cut -# the insert method can be inherited from FS::Record +#false laziness w/queue.pm +sub insert { + my $self = shift; + my $options = shift; + 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 $error = $self->SUPER::insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + foreach my $optionname ( keys %{$options} ) { + my $part_export_option = new FS::part_export_option ( { + 'exportnum' => $self->exportnum, + 'optionname' => $optionname, + 'optionvalue' => $options->{$optionname}, + } ); + $error = $part_export_option->insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + } + + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + + ''; + +}; =item delete @@ -78,16 +145,105 @@ Delete this record from the database. =cut -# the delete method can be inherited from FS::Record +#foreign keys would make this much less tedious... grr dumb mysql +sub delete { + my $self = shift; + 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 $error = $self->SUPER::delete; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + foreach my $part_export_option ( $self->part_export_option ) { + my $error = $part_export_option->delete; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + } + + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + + ''; + +} -=item replace OLD_RECORD +=item replace OLD_RECORD HASHREF Replaces the OLD_RECORD with this one in the database. If there is an error, returns the error, otherwise returns false. +If a hash reference of options is supplied, part_export_option records are +created or modified (see L). + =cut -# the replace method can be inherited from FS::Record +sub replace { + my $self = shift; + my $old = shift; + my $options = shift; + 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 $error = $self->SUPER::replace($old); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + foreach my $optionname ( keys %{$options} ) { + my $old = qsearchs( 'part_export_option', { + 'exportnum' => $self->exportnum, + 'optionname' => $optionname, + } ); + my $new = new FS::part_export_option ( { + 'exportnum' => $self->exportnum, + 'optionname' => $optionname, + 'optionvalue' => $options->{$optionname}, + } ); + $new->optionnum($old->optionnum) if $old; + my $error = $old ? $new->replace($old) : $new->insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + } + + #remove extraneous old options + foreach my $opt ( + grep { !exists $options->{$_->optionname} } $old->part_export_option + ) { + my $error = $opt->delete; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + } + + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + + ''; + +}; =item check @@ -101,6 +257,7 @@ sub check { my $self = shift; my $error = $self->ut_numbern('exportnum') + || $self->ut_domain('machine') || $self->ut_number('svcpart') || $self->ut_alpha('exporttype') ; @@ -121,12 +278,141 @@ sub check { ''; #no error } +=item part_svc + +Returns the service definition (see L) for this export. + +=cut + +sub part_svc { + my $self = shift; + qsearchs('part_svc', { svcpart => $self->svcpart } ); +} + +=item part_export_option + +Returns all options as FS::part_export_option objects (see +L). + +=cut + +sub part_export_option { + my $self = shift; + qsearch('part_export_option', { 'exportnum' => $self->exportnum } ); +} + +=item options + +Returns a list of option names and values suitable for assigning to a hash. + +=cut + +sub options { + my $self = shift; + map { $_->optionname => $_->optionvalue } $self->part_export_option; +} + +=item option OPTIONNAME + +Returns the option value for the given name, or the empty string. + +=cut + +sub option { + my $self = shift; + my $part_export_option = + qsearchs('part_export_option', { + exportnum => $self->exportnum, + optionname => shift, + } ); + $part_export_option ? $part_export_option->optionvalue : ''; +} + +=item rebless + +Reblesses the object into the FS::part_export::EXPORTTYPE class, where +EXPORTTYPE is the object's I field. There should be better docs +on how to create new exports (and they should live in their own files and be +autoloaded-on-demand), but until then, see L. + +=cut + +sub rebless { + my $self = shift; + my $exporttype = $self->exporttype; + my $class = ref($self). "::$exporttype"; + eval "use $class;"; + bless($self, $class); +} + +=item export_insert SVC_OBJECT + +=cut + +sub export_insert { + my $self = shift; + $self->rebless; + $self->_export_insert(@_); +} + +#sub AUTOLOAD { +# my $self = shift; +# $self->rebless; +# my $method = $AUTOLOAD; +# #$method =~ s/::(\w+)$/::_$1/; #infinite loop prevention +# $method =~ s/::(\w+)$/_$1/; #infinite loop prevention +# $self->$method(@_); +#} + +=item export_replace NEW OLD + +=cut + +sub export_replace { + my $self = shift; + $self->rebless; + $self->_export_replace(@_); +} + +=item export_delete + +=cut + +sub export_delete { + my $self = shift; + $self->rebless; + $self->_export_delete(@_); +} + +#fallbacks providing useful error messages intead of infinite loops +sub _export_insert { + my $self = shift; + return "_export_insert: unknown export type ". $self->exporttype; +} + +sub _export_replace { + my $self = shift; + return "_export_replace: unknown export type ". $self->exporttype; +} + +sub _export_delete { + my $self = shift; + return "_export_delete: unknown export type ". $self->exporttype; +} + =back +=head1 NEW EXPORT CLASSES + +Should be added to httemplate/edit/part_export.cgi and a module should +be FS/FS/part_export/ (an example may be found in eg/export_template.pm) + =head1 BUGS Probably. +Hmm... cust_export class (not necessarily a database table...) ... ? + =head1 SEE ALSO L, L, L, L,