From 622430cfb5bb1b9886e00a835d96b8434d6ef1db Mon Sep 17 00:00:00 2001 From: Kyle M Hall Date: Thu, 26 Apr 2012 16:08:57 -0400 Subject: [PATCH] Bug 8015: Add MARC Modifications Templates The MARC Modification Templates system gives Koha users the power to make alterations to MARC records automatically while staging MARC records for import. This tool is useful for altering MARC records from various venders work with your MARC framework. The system essentially allows one to create a basic script using actions to Copy, Move, Add, Update and Delete fields. Each action can also have an optional condition to check the value or existance of another field. The Copy & Move actions also support Regular Expressions, which can be used to automatically modify field values during the copy/move. An example would be to strip out the '$' character in field 020$c. Furthermore, the value for an update can include variables that change each time the template is used. Currently, the system supports two variables, __BRANCHCODE__ which is replaced with the branchcode of the library currently using the template, and __CURRENTDATE__ which is replaced with the current date in ISO format ( YYYY-MM-DD ). At its simplist, it can perform functions such as: Copy field 092$a to 952$c At its most complex it can run actions like: Copy field 020$c to 020$c using RegEx s/\$// if 020$c equals RegEx m/^\$/ Signed-off-by: Leila Signed-off-by: Galen Charlton --- C4/ImportBatch.pm | 6 +- C4/Koha.pm | 17 + Koha/MarcModificationTemplates.pm | 579 ++++++++++++++++++ Koha/SimpleMARC.pm | 331 ++++++++++ .../mysql/en/mandatory/userpermissions.sql | 1 + installer/data/mysql/kohastructure.sql | 35 ++ installer/data/mysql/updatedatabase.pl | 39 ++ .../prog/en/includes/tools-menu.inc | 3 + .../prog/en/modules/admin/admin-home.tt | 4 +- .../tools/marc_modification_templates.tt | 492 +++++++++++++++ .../en/modules/tools/stage-marc-import.tt | 17 + .../prog/en/modules/tools/tools-home.tt | 7 +- tools/marc_modification_templates.pl | 151 +++++ tools/stage-marc-import.pl | 11 +- 14 files changed, 1688 insertions(+), 5 deletions(-) create mode 100644 Koha/MarcModificationTemplates.pm create mode 100644 Koha/SimpleMARC.pm create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/tools/marc_modification_templates.tt create mode 100755 tools/marc_modification_templates.pl diff --git a/C4/ImportBatch.pm b/C4/ImportBatch.pm index 61d5b86133..02f242433d 100644 --- a/C4/ImportBatch.pm +++ b/C4/ImportBatch.pm @@ -26,6 +26,7 @@ use C4::Biblio; use C4::Items; use C4::Charset; use C4::AuthoritiesMarc; +use Koha::MarcModificationTemplates; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); @@ -316,7 +317,7 @@ sub ModAuthInBatch { =head2 BatchStageMarcRecords ($batch_id, $num_records, $num_items, @invalid_records) = - BatchStageMarcRecords($record_type, $encoding, $marc_records, $file_name, + BatchStageMarcRecords($encoding, $marc_records, $file_name, $marc_modification_template, $comments, $branch_code, $parse_items, $leave_as_staging, $progress_interval, $progress_callback); @@ -328,6 +329,7 @@ sub BatchStageMarcRecords { my $encoding = shift; my $marc_records = shift; my $file_name = shift; + my $marc_modification_template = shift; my $comments = shift; my $branch_code = shift; my $parse_items = shift; @@ -378,6 +380,8 @@ sub BatchStageMarcRecords { $encoding = $charset_guessed unless $encoding; + ModifyRecordWithTemplate( $marc_modification_template, $marc_record ) if ( $marc_modification_template ); + my $import_record_id; if (scalar($marc_record->fields()) == 0) { push @invalid_records, $marc_blob; diff --git a/C4/Koha.pm b/C4/Koha.pm index 937ac5f757..28ac1aa3b7 100644 --- a/C4/Koha.pm +++ b/C4/Koha.pm @@ -1486,6 +1486,23 @@ sub _isbn_cleanup { return; } +=head2 + + Log( $message ); + + Writes data to /tmp/koha.log. + + This is useful for debugging forked processes + that do not write to the apache error log + +=cut + +sub Log { + my ($data) = @_; + open (MYFILE, '>>/tmp/koha.log'); + print MYFILE "$data\n"; + close (MYFILE); +} 1; __END__ diff --git a/Koha/MarcModificationTemplates.pm b/Koha/MarcModificationTemplates.pm new file mode 100644 index 0000000000..86a03e6d86 --- /dev/null +++ b/Koha/MarcModificationTemplates.pm @@ -0,0 +1,579 @@ +package Koha::MarcModificationTemplates; + +# Copyright 2010 Kyle M Hall +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +## NOTE: +## Parts of this module are used from cgi scripts that are detached from apache before +## execution. For this reason, the C4::Koha::Log function has been used to capture +## output for debugging purposes. + +use strict; +use warnings; + +use DateTime; + +use C4::Context; +use Koha::SimpleMARC; + +use vars qw($VERSION @ISA @EXPORT); + +use constant DEBUG => 0; + +BEGIN { + $VERSION = 1.00; # set the version for version checking + @ISA = qw(Exporter); + @EXPORT = qw( + &GetModificationTemplates + &AddModificationTemplate + &DelModificationTemplate + + &GetModificationTemplateAction + &GetModificationTemplateActions + + &AddModificationTemplateAction + &ModModificationTemplateAction + &DelModificationTemplateAction + &MoveModificationTemplateAction + + &ModifyRecordsWithTemplate + &ModifyRecordWithTemplate + ); +} + + +=head1 NAME + +Koha::MarcModificationTemplates - Module to manage MARC Modification Templates + +=head1 DESCRIPTION + +MARC Modification Templates are a tool for marc batch imports, +so that librarians can set up templates for various vendors' +files telling Koha what fields to insert data into. + +=head1 FUNCTIONS + +=cut + +=head2 GetModificationTemplates + + my @templates = GetModificationTemplates( [ $template_id ] ); + + Passing a $template_id will mark the given id as the selected template. +=cut + +sub GetModificationTemplates { + my ( $template_id ) = @_; + C4::Koha::Log("Koha::MarcModificationTemplates::GetModificationTemplates( $template_id )") if DEBUG; + warn("Koha::MarcModificationTemplates::GetModificationTemplates( $template_id )") if DEBUG; + + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare("SELECT * FROM marc_modification_templates"); + $sth->execute(); + + my @templates; + while ( my $template = $sth->fetchrow_hashref() ) { + $template->{'selected'} = 1 if ( $template->{'template_id'} eq $template_id ); + push( @templates, $template ); + } + + return @templates; +} + +=head2 + AddModificationTemplate + + $template_id = AddModificationTemplate( $template_name[, $template_id ] ); + + If $template_id is supplied, the actions from that template will be copied + into the newly created template. +=cut + +sub AddModificationTemplate { + my ( $template_name, $template_id_copy ) = @_; + + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare("INSERT INTO marc_modification_templates ( name ) VALUES ( ? )"); + $sth->execute( $template_name ); + + $sth = $dbh->prepare("SELECT * FROM marc_modification_templates WHERE name = ?"); + $sth->execute( $template_name ); + my $row = $sth->fetchrow_hashref(); + my $template_id = $row->{'template_id'}; + + if ( $template_id_copy ) { + my @actions = GetModificationTemplateActions( $template_id_copy ); + foreach my $action ( @actions ) { + AddModificationTemplateAction( + $template_id, + $action->{'action'}, + $action->{'field_number'}, + $action->{'from_field'}, + $action->{'from_subfield'}, + $action->{'field_value'}, + $action->{'to_field'}, + $action->{'to_subfield'}, + $action->{'to_regex'}, + $action->{'conditional'}, + $action->{'conditional_field'}, + $action->{'conditional_subfield'}, + $action->{'conditional_comparison'}, + $action->{'conditional_value'}, + $action->{'conditional_regex'}, + $action->{'description'}, + ); + + } + } + + return $template_id; +} + +=head2 + DelModificationTemplate + + DelModificationTemplate( $template_id ); +=cut + +sub DelModificationTemplate { + my ( $template_id ) = @_; + + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare("DELETE FROM marc_modification_templates WHERE template_id = ?"); + $sth->execute( $template_id ); + + $sth = $dbh->prepare("DELETE FROM marc_modification_template_actions WHERE template_id = ?"); + $sth->execute( $template_id ); +} + +=head2 + GetModificationTemplateAction + + my $action = GetModificationTemplateAction( $mmta_id ); +=cut + +sub GetModificationTemplateAction { + my ( $mmta_id ) = @_; + + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare("SELECT * FROM marc_modification_template_actions WHERE mmta_id = ?"); + $sth->execute( $mmta_id ); + my $action = $sth->fetchrow_hashref(); + + return $action; +} + +=head2 + GetModificationTemplateActions + + my @actions = GetModificationTemplateActions( $template_id ); +=cut + +sub GetModificationTemplateActions { + my ( $template_id ) = @_; + + C4::Koha::Log( "Koha::MarcModificationTemplates::GetModificationTemplateActions( $template_id )" ) if DEBUG; + warn( "Koha::MarcModificationTemplates::GetModificationTemplateActions( $template_id )" ) if DEBUG; + + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare("SELECT * FROM marc_modification_template_actions WHERE template_id = ? ORDER BY ordering"); + $sth->execute( $template_id ); + + my @actions; + while ( my $action = $sth->fetchrow_hashref() ) { + push( @actions, $action ); + } + + C4::Koha::Log( Data::Dumper::Dumper( @actions ) ) if DEBUG > 4; + warn( Data::Dumper::Dumper( @actions ) ) if DEBUG > 4; + + return @actions; +} + +=head2 + AddModificationTemplateAction + + AddModificationTemplateAction( + $template_id, $action, $field_number, + $from_field, $from_subfield, $field_value, + $to_field, $to_subfield, $to_regex, + $conditional, $conditional_field, $conditional_subfield, + $conditional_comparison, $conditional_value, + $conditional_regex, $description + ); + + Adds a new action to the given modification template. + +=cut + +sub AddModificationTemplateAction { + my ( + $template_id, + $action, + $field_number, + $from_field, + $from_subfield, + $field_value, + $to_field, + $to_subfield, + $to_regex, + $conditional, + $conditional_field, + $conditional_subfield, + $conditional_comparison, + $conditional_value, + $conditional_regex, + $description + ) = @_; + + C4::Koha::Log( "Koha::MarcModificationTemplates::AddModificationTemplateAction( $template_id, $action, + $field_number, $from_field, $from_subfield, $field_value, $to_field, $to_subfield, + $to_regex, $conditional, $conditional_field, $conditional_subfield, $conditional_comparison, + $conditional_value, $conditional_regex, $description )" ) if DEBUG; + warn( "Koha::MarcModificationTemplates::AddModificationTemplateAction( $template_id, $action, + $field_number, $from_field, $from_subfield, $field_value, $to_field, $to_subfield, + $to_regex, $conditional, $conditional_field, $conditional_subfield, $conditional_comparison, + $conditional_value, $conditional_regex, $description )" ) if DEBUG; + + $conditional_regex ||= '0'; + + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare( 'SELECT MAX(ordering) + 1 AS next_ordering FROM marc_modification_template_actions WHERE template_id = ?' ); + $sth->execute( $template_id ); + my $row = $sth->fetchrow_hashref; + my $ordering = $row->{'next_ordering'} || 1; + + my $query = " + INSERT INTO marc_modification_template_actions ( + mmta_id, + template_id, + ordering, + action, + field_number, + from_field, + from_subfield, + field_value, + to_field, + to_subfield, + to_regex, + conditional, + conditional_field, + conditional_subfield, + conditional_comparison, + conditional_value, + conditional_regex, + description + ) + VALUES ( NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )"; + + $sth = $dbh->prepare( $query ); + + $sth->execute( + $template_id, + $ordering, + $action, + $field_number, + $from_field, + $from_subfield, + $field_value, + $to_field, + $to_subfield, + $to_regex, + $conditional, + $conditional_field, + $conditional_subfield, + $conditional_comparison, + $conditional_value, + $conditional_regex, + $description + ); +} + +=head2 + ModModificationTemplateAction + + ModModificationTemplateAction( + $mmta_id, $action, $field_number, $from_field, + $from_subfield, $field_value, $to_field, + $to_subfield, $to_regex, $conditional, + $conditional_field, $conditional_subfield, + $conditional_comparison, $conditional_value, + $conditional_regex, $description + ); + + Modifies an existing action. + +=cut + +sub ModModificationTemplateAction { + my ( + $mmta_id, + $action, + $field_number, + $from_field, + $from_subfield, + $field_value, + $to_field, + $to_subfield, + $to_regex, + $conditional, + $conditional_field, + $conditional_subfield, + $conditional_comparison, + $conditional_value, + $conditional_regex, + $description + ) = @_; + + my $dbh = C4::Context->dbh; + + my $query = " + UPDATE marc_modification_template_actions SET + action = ?, + field_number = ?, + from_field = ?, + from_subfield = ?, + field_value = ?, + to_field = ?, + to_subfield = ?, + to_regex = ?, + conditional = ?, + conditional_field = ?, + conditional_subfield = ?, + conditional_comparison = ?, + conditional_value = ?, + conditional_regex = ?, + description = ? + WHERE mmta_id = ?"; + + my $sth = $dbh->prepare( $query ); + + $sth->execute( + $action, + $field_number, + $from_field, + $from_subfield, + $field_value, + $to_field, + $to_subfield, + $to_regex, + $conditional, + $conditional_field, + $conditional_subfield, + $conditional_comparison, + $conditional_value, + $conditional_regex, + $description, + $mmta_id + ); +} + + +=head2 + DelModificationTemplateAction + + DelModificationTemplateAction( $mmta_id ); + + Deletes the given template action. +=cut + +sub DelModificationTemplateAction { + my ( $mmta_id ) = @_; + + my $action = GetModificationTemplateAction( $mmta_id ); + + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare("DELETE FROM marc_modification_template_actions WHERE mmta_id = ?"); + $sth->execute( $mmta_id ); + + $sth = $dbh->prepare("UPDATE marc_modification_template_actions SET ordering = ordering - 1 WHERE template_id = ? AND ordering > ?"); + $sth->execute( $action->{'template_id'}, $action->{'ordering'} ); +} + +=head2 + MoveModificationTemplateAction + + MoveModificationTemplateAction( $mmta_id, $where ); + + Changes the order for the given action. + Options for $where are 'up', 'down', 'top' and 'bottom' +=cut +sub MoveModificationTemplateAction { + my ( $mmta_id, $where ) = @_; + + my $action = GetModificationTemplateAction( $mmta_id ); + + return if ( $action->{'ordering'} eq '1' && ( $where eq 'up' || $where eq 'top' ) ); + return if ( $action->{'ordering'} eq GetModificationTemplateActions( $action->{'template_id'} ) && ( $where eq 'down' || $where eq 'bottom' ) ); + + my $dbh = C4::Context->dbh; + my ( $sth, $query ); + + if ( $where eq 'up' || $where eq 'down' ) { + + ## For up and down, we just swap the ordering number with the one above or below it. + + ## Change the ordering for the other action + $query = "UPDATE marc_modification_template_actions SET ordering = ? WHERE template_id = ? AND ordering = ?"; + + my $ordering = $action->{'ordering'}; + $ordering-- if ( $where eq 'up' ); + $ordering++ if ( $where eq 'down' ); + + $sth = $dbh->prepare( $query ); + $sth->execute( $action->{'ordering'}, $action->{'template_id'}, $ordering ); + + ## Change the ordering for this action + $query = "UPDATE marc_modification_template_actions SET ordering = ? WHERE mmta_id = ?"; + $sth = $dbh->prepare( $query ); + $sth->execute( $ordering, $action->{'mmta_id'} ); + + } elsif ( $where eq 'top' ) { + + $sth = $dbh->prepare('UPDATE marc_modification_template_actions SET ordering = ordering + 1 WHERE template_id = ? AND ordering < ?'); + $sth->execute( $action->{'template_id'}, $action->{'ordering'} ); + + $sth = $dbh->prepare('UPDATE marc_modification_template_actions SET ordering = 1 WHERE mmta_id = ?'); + $sth->execute( $mmta_id ); + + } elsif ( $where eq 'bottom' ) { + + my $ordering = GetModificationTemplateActions( $action->{'template_id'} ); + + $sth = $dbh->prepare('UPDATE marc_modification_template_actions SET ordering = ordering - 1 WHERE template_id = ? AND ordering > ?'); + $sth->execute( $action->{'template_id'}, $action->{'ordering'} ); + + $sth = $dbh->prepare('UPDATE marc_modification_template_actions SET ordering = ? WHERE mmta_id = ?'); + $sth->execute( $ordering, $mmta_id ); + + } + +} + +=head2 + ModifyRecordsWithTemplate + + ModifyRecordsWithTemplate( $template_id, $batch ); + + Accepts a template id and a MARC::Batch object. +=cut + +sub ModifyRecordsWithTemplate { + my ( $template_id, $batch ) = @_; + C4::Koha::Log( "Koha::MarcModificationTemplates::ModifyRecordsWithTemplate( $template_id, $batch )" ) if DEBUG; + warn( "Koha::MarcModificationTemplates::ModifyRecordsWithTemplate( $template_id, $batch )" ) if DEBUG; + + while ( my $record = $batch->next() ) { + ModifyRecordWithTemplate( $template_id, $record ); + } +} + +=head2 + ModifyRecordWithTemplate + + ModifyRecordWithTemplate( $template_id, $record ) + + Accepts a MARC::Record object ( $record ) and modifies + it based on the actions for the given $template_id +=cut + +sub ModifyRecordWithTemplate { + my ( $template_id, $record ) = @_; + C4::Koha::Log( "Koha::MarcModificationTemplates::ModifyRecordWithTemplate( $template_id, $record )" ) if DEBUG; + warn( "Koha::MarcModificationTemplates::ModifyRecordWithTemplate( $template_id, $record )" ) if DEBUG; + C4::Koha::Log( "Unmodified Record:\n" . $record->as_formatted() ) if DEBUG >= 10; + warn( "Unmodified Record:\n" . $record->as_formatted() ) if DEBUG >= 10; + + my $current_date = DateTime->now()->ymd(); + my $branchcode = C4::Context->userenv->{branch}; + + my @actions = GetModificationTemplateActions( $template_id ); + + foreach my $a ( @actions ) { + my $action = $a->{'action'}; + my $field_number = $a->{'field_number'}; + my $from_field = $a->{'from_field'}; + my $from_subfield = $a->{'from_subfield'}; + my $field_value = $a->{'field_value'}; + my $to_field = $a->{'to_field'}; + my $to_subfield = $a->{'to_subfield'}; + my $to_regex = $a->{'to_regex'}; + my $conditional = $a->{'conditional'}; + my $conditional_field = $a->{'conditional_field'}; + my $conditional_subfield = $a->{'conditional_subfield'}; + my $conditional_comparison = $a->{'conditional_comparison'}; + my $conditional_value = $a->{'conditional_value'}; + my $conditional_regex = $a->{'conditional_regex'}; + + my $eval = "$action( \$record, '$from_field', '$from_subfield', "; + + if ( $field_value ) { + C4::Koha::Log( "Field value before replacements: $field_value" ) if ( DEBUG >= 3 ); + warn( "Field value before replacements: $field_value" ) if ( DEBUG >= 3 ); + + $field_value =~ s/__CURRENTDATE__/$current_date/g; + $field_value =~ s/__BRANCHCODE__/$branchcode/g; + + $eval .= " '$field_value' "; + + C4::Koha::Log( "Field value after replacements: $field_value" ) if ( DEBUG >= 3 ); + warn( "Field value after replacements: $field_value" ) if ( DEBUG >= 3 ); + } elsif ( $to_field ) { + $eval .= " '$to_field', '$to_subfield', '$to_regex' "; + } + + $eval .= ", '$field_number' " if ( $field_number ); + $eval .= ') '; + + if ( $conditional ) { + $eval .= " $conditional ( "; + + if ( $conditional_comparison eq 'exists' ) { + $eval .= "field_exists( \$record, '$conditional_field', '$conditional_subfield' )"; + + } elsif ( $conditional_comparison eq 'not_exists' ) { + $eval .= "!field_exists( \$record, '$conditional_field', '$conditional_subfield' )"; + + } elsif ( $conditional_comparison eq 'equals' ) { + $eval .= "field_equals( \$record, '$conditional_value', '$conditional_field', '$conditional_subfield', '$conditional_regex' ) "; + + } elsif ( $conditional_comparison eq 'not_equals' ) { + $eval .= "!field_equals( \$record, '$conditional_value', '$conditional_field', '$conditional_subfield', '$conditional_regex' ) "; + } + + $eval .= " )"; + } + + $eval .= ";"; + + C4::Koha::Log("eval $eval") if DEBUG >= 2; + warn("eval $eval") if DEBUG >= 2; + eval $eval; + C4::Koha::Log( $record->as_formatted() ) if DEBUG >= 10; + warn( $record->as_formatted() ) if DEBUG >= 10; + + } +} +1; +__END__ + +=head1 AUTHOR + +Kyle M Hall + +=cut diff --git a/Koha/SimpleMARC.pm b/Koha/SimpleMARC.pm new file mode 100644 index 0000000000..96a3af106d --- /dev/null +++ b/Koha/SimpleMARC.pm @@ -0,0 +1,331 @@ +package Koha::SimpleMARC; + +# Copyright 2009 Kyle M. Hall + +use strict; +use warnings; + +#use MARC::Record; + +require Exporter; + +our @ISA = qw(Exporter); +our %EXPORT_TAGS = ( 'all' => [ qw( + +) ] ); + +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); + +our @EXPORT = qw( + read_field + update_field + copy_field + move_field + delete_field + field_exists + field_equals +); + +our $VERSION = '0.01'; + +our $debug = 0; + +=head1 NAME + +SimpleMARC - Perl modle for making simple MARC record alterations. + +=head1 SYNOPSIS + + use SimpleMARC; + +=head1 DESCRIPTION + +SimpleMARC is designed to make writing scripts +to modify MARC records simple and easy. + +Every function in the modules requires a +MARC::Record object as its first parameter. + +=head1 AUTHOR + +Kyle Hall kyle.m.hall@gmail.com + +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2009 by Kyle Hall + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself, either Perl version 5.8.7 or, +at your option, any later version of Perl 5 you may have available. + +=head1 FUNCTIONS + +=head2 + + copy_field( $record, $fromFieldName, $fromSubfieldName, $toFieldName, $toSubfieldName[, $regex[, $n ] ] ); + + Copies a value from one field to another. If a regular expression ( $regex ) is supplied, + the value will be transformed by the given regex before being copied into the new field. + Example: $regex = 's/Old Text/Replacement Text/' + + If $n is passed, copy_field will only copy the Nth field of the list of fields. + E.g. $n = 1 will only use the first field's value, $n = 2 will use only the 2nd field's value. + +=cut + +sub copy_field { + my ( $record, $fromFieldName, $fromSubfieldName, $toFieldName, $toSubfieldName, $regex, $n ) = @_; + C4::Koha::Log( "C4::SimpleMARC::copy_field( '$record', '$fromFieldName', '$fromSubfieldName', '$toFieldName', '$toSubfieldName', '$regex', '$n' )" ) if $debug; + + if ( ! ( $record && $fromFieldName && $toFieldName ) ) { return; } + + my @values = read_field( $record, $fromFieldName, $fromSubfieldName ); + @values = ( $values[$n-1] ) if ( $n ); + C4::Koha::Log( "@values = read_field( $record, $fromFieldName, $fromSubfieldName )" ) if $debug >= 3; + + if ( $regex ) { + foreach my $value ( @values ) { + C4::Koha::Log( "\$value =~ s$regex" ) if ( $debug >= 3 ); + eval "\$value =~ s$regex"; + } + } + + update_field( $record, $toFieldName, $toSubfieldName, @values ); + +} + +=head2 + + update_field( $record, $fieldName, $subfieldName, $value[, $value,[ $value ... ] ] ); + + Updates a field with the given value, creating it if neccessary. + + If multiple values are supplied, they will be used to update a list of repeatable fields + until either the fields or the values are all used. + + If a single value is supplied for a repeated field, that value will be used to update + each of the repeated fields. + +=cut + +sub update_field { + my ( $record, $fieldName, $subfieldName, @values ) = @_; + C4::Koha::Log( "C4::SimpleMARC::update_field( $record, $fieldName, $subfieldName, @values )" ) if $debug; + + if ( ! ( $record && $fieldName ) ) { return; } + + if ( @values eq 1 ) { + _update_repeatable_field_with_single_value( $record, $fieldName, $subfieldName, @values ); + return; + } + + my $i = 0; + my $field; + if ( $subfieldName ) { + if ( my @fields = $record->field( $fieldName ) ) { + foreach my $field ( @fields ) { + $field->update( "$subfieldName" => $values[$i++] ); + } + } else { + ## Field does not exist, create it. + foreach my $value ( @values ) { + $field = MARC::Field->new( $fieldName, '', '', "$subfieldName" => $values[$i++] ); + $record->append_fields( $field ); + } + } + } else { ## No subfield + if ( my @fields = $record->field( $fieldName ) ) { + foreach my $field ( @fields ) { + $field->update( $values[$i++] ); + } + } else { + ## Field does not exists, create it + foreach my $value ( @values ) { + $field = MARC::Field->new( $fieldName, $value ); + $record->append_fields( $field ); + } + } + } +} + +=head2 + + my @values = read_field( $record, $fieldName[, $subfieldName, [, $n ] ] ); + + Returns an array of field values for the given field and subfield + + If $n is given, it will return only the $nth value of the array. + E.g. If $n = 1, it return the 1st value, if $n = 3, it will return the 3rd value. + +=cut + +sub read_field { + my ( $record, $fieldName, $subfieldName, $n ) = @_; + C4::Koha::Log( "C4::SimpleMARC::read_field( '$record', '$fieldName', '$subfieldName', '$n' )" ) if $debug; + + my @fields = $record->field( $fieldName ); + + return @fields unless $subfieldName; + + my @subfields; + foreach my $field ( @fields ) { + my @sf = $field->subfield( $subfieldName ); + push( @subfields, @sf ); + } + + if ( $n ) { + return $subfields[$n-1]; + } else { + return @subfields; + } +} + +=head2 + + $bool = field_exists( $record, $fieldName[, $subfieldName ]); + + Returns true if the field exits, false otherwise. + +=cut + +sub field_exists { + my ( $record, $fieldName, $subfieldName ) = @_; + C4::Koha::Log( "C4::SimpleMARC::field_exists( $record, $fieldName, $subfieldName )" ) if $debug; + + if ( ! $record ) { return; } + + my $return = 0; + if ( $fieldName && $subfieldName ) { + $return = $record->field( $fieldName ) && $record->subfield( $fieldName, $subfieldName ); + } elsif ( $fieldName ) { + $return = $record->field( $fieldName ) && 1; + } + + C4::Koha::Log( "C4:SimpleMARC::field_exists: Returning '$return'" ) if $debug >= 2; + return $return; +} + +=head2 + + $bool = field_equals( $record, $value, $fieldName[, $subfieldName[, $regex [, $n ] ] ]); + + Returns true if the field equals the given value, false otherwise. + + If a regular expression ( $regex ) is supplied, the value will be compared using + the given regex. Example: $regex = 'm/sought_text/' + + If $n is passed, the Nth field of a repeatable series will be used for comparison. + Set $n to 1 or leave empty for a non-repeatable field. + +=cut + +sub field_equals { + my ( $record, $value, $fieldName, $subfieldName, $regex, $n ) = @_; + $n = 1 unless ( $n ); ## $n defaults to first field of a repeatable field series + C4::Koha::Log( "C4::SimpleMARC::field_equals( '$record', '$value', '$fieldName', '$subfieldName', '$regex', '$n')" ) if $debug; + + if ( ! $record ) { return; } + + my @field_values = read_field( $record, $fieldName, $subfieldName, $n ); + my $field_value = $field_values[$n-1]; + + if ( $regex ) { + C4::Koha::Log( "Testing '$field_value' =~ m$value" ) if $debug >= 3; + return eval "\$field_value =~ m$value"; + } else { + return $field_value eq $value; + } +} + +=head2 + + move_field( $record, $fromFieldName, $fromSubfieldName, $toFieldName, $toSubfieldName[, $regex [, $n ] ] ); + + Moves a value from one field to another. If a regular expression ( $regex ) is supplied, + the value will be transformed by the given regex before being moved into the new field. + Example: $regex = 's/Old Text/Replacement Text/' + + If $n is passed, only the Nth field will be moved. $n = 1 + will move the first repeatable field, $n = 3 will move the third. + +=cut + +sub move_field { + my ( $record, $fromFieldName, $fromSubfieldName, $toFieldName, $toSubfieldName, $regex, $n ) = @_; + C4::Koha::Log( "C4::SimpleMARC::move_field( '$record', '$fromFieldName', '$fromSubfieldName', '$toFieldName', '$toSubfieldName', '$regex', '$n' )" ) if $debug; + copy_field( $record, $fromFieldName, $fromSubfieldName, $toFieldName, $toSubfieldName, $regex, $n ); + delete_field( $record, $fromFieldName, $fromSubfieldName, $n ); +} + +=head2 + + delete_field( $record, $fieldName[, $subfieldName [, $n ] ] ); + + Deletes the given field. + + If $n is passed, only the Nth field will be deleted. $n = 1 + will delete the first repeatable field, $n = 3 will delete the third. + +=cut + +sub delete_field { + my ( $record, $fieldName, $subfieldName, $n ) = @_; + C4::Koha::Log( "C4::SimpleMARC::delete_field( '$record', '$fieldName', '$subfieldName', '$n' )" ) if $debug; + + my @fields = $record->field( $fieldName ); + + @fields = ( $fields[$n-1] ) if ( $n ); + + if ( @fields && !$subfieldName ) { + foreach my $field ( @fields ) { + $record->delete_field( $field ); + } + } elsif ( @fields && $subfieldName ) { + foreach my $field ( @fields ) { + $field->delete_subfield( code => $subfieldName ); + } + } +} + +=head2 + + _update_repeatable_field_with_single_value( $record, $fieldName, $subfieldName, $value ); + + Updates a repeatable field, giving all existing copies of that field the given value. + + This is an internal function, and thus is not exported. + +=cut + +sub _update_repeatable_field_with_single_value { + my ( $record, $fieldName, $subfieldName, $value ) = @_; + C4::Koha::Log( "C4::SimpleMARC::_update_repeatable_field_with_single_value( $record, $fieldName, $subfieldName, $value )" ) if $debug; + + if ( ! ( $record && $fieldName ) ) { return; } + + my $field; + if ( $subfieldName ) { + if ( my @fields = $record->field( $fieldName ) ) { + foreach my $field ( @fields ) { + $field->update( "$subfieldName" => $value ); + } + } else { + ## Field does not exist, create it. + $field = MARC::Field->new( $fieldName, '', '', "$subfieldName" => $value ); + $record->append_fields( $field ); + } + } else { ## No subfield + if ( my @fields = $record->field( $fieldName ) ) { + foreach my $field ( @fields ) { + $field->update( $value ); + } + } else { + ## Field does not exists, create it + $field = MARC::Field->new( $fieldName, $value ); + $record->append_fields( $field ); + } + } +} + +1; +__END__ diff --git a/installer/data/mysql/en/mandatory/userpermissions.sql b/installer/data/mysql/en/mandatory/userpermissions.sql index 50387c5acf..7874c9e8ca 100644 --- a/installer/data/mysql/en/mandatory/userpermissions.sql +++ b/installer/data/mysql/en/mandatory/userpermissions.sql @@ -45,6 +45,7 @@ INSERT INTO permissions (module_bit, code, description) VALUES (13, 'rotating_collections', 'Manage rotating collections'), (13, 'upload_local_cover_images', 'Upload local cover images'), (13, 'manage_patron_lists', 'Add, edit and delete patron lists and their contents'), + (13, 'marc_modification_templates', 'Manage marc modification templates'), (15, 'check_expiration', 'Check the expiration of a serial'), (15, 'claim_serials', 'Claim missing serials'), (15, 'create_subscription', 'Create a new subscription'), diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index 46814a93ea..f337a97fb0 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -3348,6 +3348,41 @@ ALTER TABLE `patron_list_patrons` ADD CONSTRAINT patron_list_patrons_ibfk_1 FOREIGN KEY (patron_list_id) REFERENCES patron_lists (patron_list_id) ON DELETE CASCADE ON UPDATE CASCADE, ADD CONSTRAINT patron_list_patrons_ibfk_2 FOREIGN KEY (borrowernumber) REFERENCES borrowers (borrowernumber) ON DELETE CASCADE ON UPDATE CASCADE; +-- +-- Table structure for table 'marc_modification_templates' +-- + +CREATE TABLE IF NOT EXISTS marc_modification_templates ( + template_id int(11) NOT NULL AUTO_INCREMENT, + name text NOT NULL, + PRIMARY KEY (template_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Table structure for table 'marc_modification_template_actions' +-- + +CREATE TABLE IF NOT EXISTS marc_modification_template_actions ( + mmta_id int(11) NOT NULL AUTO_INCREMENT, + template_id int(11) NOT NULL, + ordering int(3) NOT NULL, + action enum('delete_field','update_field','move_field','copy_field') NOT NULL, + field_number smallint(6) NOT NULL DEFAULT '0', + from_field varchar(3) NOT NULL, + from_subfield varchar(1) DEFAULT NULL, + field_value varchar(100) DEFAULT NULL, + to_field varchar(3) DEFAULT NULL, + to_subfield varchar(1) DEFAULT NULL, + to_regex text, + conditional enum('if','unless') DEFAULT NULL, + conditional_field varchar(3) DEFAULT NULL, + conditional_subfield varchar(1) DEFAULT NULL, + conditional_comparison enum('exists','not_exists','equals','not_equals') DEFAULT NULL, + conditional_value text, + conditional_regex tinyint(1) NOT NULL DEFAULT '0', + description text, + PRIMARY KEY (mmta_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index 721a9d1db6..1af6a0fb45 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -7686,6 +7686,45 @@ if ( CheckVersion($DBversion) ) { SetVersion($DBversion); } +$DBversion = "3.11.00.XXX"; +if (C4::Context->preference("Version") < TransformToNum($DBversion)) { + $dbh->do("CREATE TABLE IF NOT EXISTS marc_modification_templates ( + template_id int(11) NOT NULL auto_increment, + name text NOT NULL, + PRIMARY KEY (template_id) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8;" + ); + + $dbh->do(" + CREATE TABLE IF NOT EXISTS marc_modification_template_actions ( + mmta_id int(11) NOT NULL auto_increment, + template_id int(11) NOT NULL, + ordering int(3) NOT NULL, + action enum('delete_field','update_field','move_field','copy_field') NOT NULL, + field_number smallint(6) NOT NULL default '0', + from_field varchar(3) NOT NULL, + from_subfield varchar(1) NULL, + field_value varchar(100) default NULL, + to_field varchar(3) default NULL, + to_subfield varchar(1) default NULL, + to_regex text, + conditional enum('if','unless') default NULL, + conditional_field varchar(3) default NULL, + conditional_subfield varchar(1) default NULL, + conditional_comparison enum('exists','not_exists','equals','not_equals') default NULL, + conditional_value text, + conditional_regex tinyint(1) NOT NULL default '0', + description text, + PRIMARY KEY (mmta_id) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + "); + + $dbh->do("INSERT INTO permissions (module_bit, code, description) VALUES ('13', 'marc_modification_templates', 'Manage marc modification templates')"); + + print "Upgrade to $DBversion done ( Added tables for MARC Modification Framework )\n"; + SetVersion($DBversion); +} + =head1 FUNCTIONS =head2 TableExists($table) diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc index dce18d5959..871803e7ca 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc @@ -71,6 +71,9 @@
  • Rotating collections
  • [% END %] --> + [% IF ( CAN_user_tools_marc_modification_templates ) %] +
  • Manage MARC modification templates
  • + [% END %] [% IF ( CAN_user_tools_stage_marc_import ) %]
  • Stage MARC for import
  • [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt index a5dbe44ada..46a3b3afff 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt @@ -68,8 +68,8 @@
    Create and manage Bibliographic frameworks that define the characteristics of your MARC Records (field and subfield definitions) as well as templates for the MARC editor.
    Koha to MARC mapping
    Define the mapping between the Koha transactional database (SQL) and the MARC Bibliographic records. Note that the mapping can be defined through MARC Bibliographic Framework. This tool is just a shortcut to speed up linkage.
    -
    Keywords to MARC mapping
    -
    Define the mapping between keywords and MARC fields, those keywords are used to find some datas independently of the framework.
    +
    Keywords to MARC mapping
    +
    Define the mapping between keywords and MARC fields, those keywords are used to find some datas independently of the framework.
    MARC Bibliographic framework test
    Checks the MARC structure. If you change your MARC Bibliographic framework it's recommended that you run this tool to test for errors in your definition.
    Authority types
    diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/marc_modification_templates.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/marc_modification_templates.tt new file mode 100644 index 0000000000..255310da9d --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/marc_modification_templates.tt @@ -0,0 +1,492 @@ +[% INCLUDE 'doc-head-open.inc' %] +Koha › Tools › MARC Modification Templates +[% INCLUDE 'doc-head-close.inc' %] + + + + + + + + +[% INCLUDE 'header.inc' %] +[% INCLUDE 'cat-search.inc' %] + + + +
    +
    +
    +

    MARC Modification Templates

    + + [% IF ( TemplatesLoop ) %] + +
    + + + + +
    + +
    + + + +
    + + + [% IF ( ActionsLoop ) %] + + + + + + + + + + + + + [% FOREACH ActionsLoo IN ActionsLoop %] + + + + + + + + + + [% END %] +
    Actions for this template
    Change OrderOrderActionDescription  
    + + Go up + + + + Go top + + + + Go bottom + + + + Go down + + [% ActionsLoo.ordering %] + [% IF ( ActionsLoo.action_delete_field ) %] Delete [% END %] + [% IF ( ActionsLoo.action_update_field ) %] Update [% END %] + [% IF ( ActionsLoo.action_move_field ) %] Move [% END %] + [% IF ( ActionsLoo.action_copy_field ) %] Copy [% END %] + + [% UNLESS ( ActionsLoo.action_update_field ) %] + [% IF ( ActionsLoo.field_number ) %] + 1st + [% END %] + [% END %] + + field + + [% ActionsLoo.from_field %][% IF ( ActionsLoo.from_subfield ) %]$[% ActionsLoo.from_subfield %][% END %] + + [% IF ( ActionsLoo.field_value ) %] + with value [% ActionsLoo.field_value %] + [% END %] + + [% IF ( ActionsLoo.to_field ) %] + to [% ActionsLoo.to_field %][% IF ( ActionsLoo.to_subfield ) %]$[% ActionsLoo.to_subfield %][% END %] + + [% IF ( ActionsLoo.to_regex ) %] + using RegEx s[% ActionsLoo.to_regex %] + [% END %] + [% END %] + + [% IF ( ActionsLoo.conditional ) %] + [% IF ( ActionsLoo.conditional_if ) %] if [% END %] + [% IF ( ActionsLoo.conditional_unless ) %] unless [% END %] + + [% ActionsLoo.conditional_field %][% IF ( ActionsLoo.conditional_subfield ) %]$[% ActionsLoo.conditional_subfield %][% END %] + + [% IF ( ActionsLoo.conditional_comparison_exists ) %] exists [% END %] + [% IF ( ActionsLoo.conditional_comparison_not_exists ) %] does not exist [% END %] + [% IF ( ActionsLoo.conditional_comparison_equals ) %] matches [% END %] + [% IF ( ActionsLoo.conditional_comparison_not_equals ) %] does not match [% END %] + + [% IF ( ActionsLoo.conditional_regex ) %] RegEx m[% END %][% ActionsLoo.conditional_value %] + [% END %] + [% ActionsLoo.description %]EditDelete
    + [% ELSE %] +

    There are no defined actions for this template.

    + [% END %] + +
    + +
    + Add A New Action + + + + + + + + field(s) + + + + + +

    + + + + + + + + + +

    + + + +

    + + +

    +
    + + [% ELSE %] +

    There are no defined templates. Please create a template first.

    + [% END %] + +
    +
    + Create A New Template + + + + + + + + [% IF ( template_id ) %] + + + + [% END %] +
    +
    + + + +
    +
    + +
    + [% INCLUDE 'tools-menu.inc' %] +
    +
    +[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/stage-marc-import.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/stage-marc-import.tt index 6c5613fcaf..b9b17f58e4 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/stage-marc-import.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/stage-marc-import.tt @@ -117,6 +117,23 @@ function CheckForm(f) { + [% IF MarcModificationTemplatesLoop %] +
    + Use MARC Modification Template: +
      +
    1. + + +
    2. +
    +
    + [% END %] +
    Look for existing records in catalog?
    1. diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt index b842f57eba..8ae069f7e8 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt @@ -145,10 +145,15 @@ + [% IF ( CAN_user_tools_marc_modification_templates ) %] +
      MARC Modification Templates
      +
      Manage templates for modifying MARC records during import.
      + [% END %] + [% IF ( CAN_user_tools_stage_marc_import ) %]
      Stage MARC records for import
      Stage MARC records into the reservoir.
      diff --git a/tools/marc_modification_templates.pl b/tools/marc_modification_templates.pl new file mode 100755 index 0000000000..60a28cf51c --- /dev/null +++ b/tools/marc_modification_templates.pl @@ -0,0 +1,151 @@ +#!/usr/bin/perl +# Copyright 2010 Kyle M Hall +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use strict; +use warnings; + +use CGI; + +use C4::Auth; +use C4::Koha; +use C4::Output; +use Koha::MarcModificationTemplates; + +my $cgi = new CGI; + +my $op = $cgi->param('op'); +my $template_id = $cgi->param('template_id'); + +my ($template, $loggedinuser, $cookie) + = get_template_and_user({template_name => "tools/marc_modification_templates.tmpl", + query => $cgi, + type => "intranet", + authnotrequired => 0, + flagsrequired => { tools => 'marc_modfication_templates' }, + debug => 1, + }); + +if ( $op eq "create_template" ) { + $template_id = '' unless $cgi->param('duplicate_current_template'); + $template_id = AddModificationTemplate( $cgi->param('template_name'), $template_id ); + +} elsif ( $op eq "delete_template" ) { + + DelModificationTemplate( $template_id ); + $template_id = ''; + +} elsif ( $op eq "add_action" ) { + + my $mmta_id = $cgi->param('mmta_id'); + my $action = $cgi->param('action'); + my $field_number = $cgi->param('field_number'); + my $from_field = $cgi->param('from_field'); + my $from_subfield = $cgi->param('from_subfield'); + my $field_value = $cgi->param('field_value'); + my $to_field = $cgi->param('to_field'); + my $to_subfield = $cgi->param('to_subfield'); + my $to_regex = $cgi->param('to_regex'); + my $conditional = $cgi->param('conditional'); + my $conditional_field = $cgi->param('conditional_field'); + my $conditional_subfield = $cgi->param('conditional_subfield'); + my $conditional_comparison = $cgi->param('conditional_comparison'); + my $conditional_value = $cgi->param('conditional_value'); + my $conditional_regex = $cgi->param('conditional_regex') eq 'on'; + my $description = $cgi->param('description'); + + unless ( $mmta_id ) { + AddModificationTemplateAction( + $template_id, + $action, + $field_number, + $from_field, + $from_subfield, + $field_value, + $to_field, + $to_subfield, + $to_regex, + $conditional, + $conditional_field, + $conditional_subfield, + $conditional_comparison, + $conditional_value, + $conditional_regex, + $description + ); + } else { + ModModificationTemplateAction( + $mmta_id, + $action, + $field_number, + $from_field, + $from_subfield, + $field_value, + $to_field, + $to_subfield, + $to_regex, + $conditional, + $conditional_field, + $conditional_subfield, + $conditional_comparison, + $conditional_value, + $conditional_regex, + $description + ); + + } + +} elsif ( $op eq "delete_action" ) { + DelModificationTemplateAction( $cgi->param('mmta_id') ); + +} elsif ( $op eq "move_action" ) { + + MoveModificationTemplateAction( $cgi->param('mmta_id'), $cgi->param('where') ); + +} + +my @templates = GetModificationTemplates( $template_id ); + +unless ( $template_id ) { + $template_id = $templates[0]->{'template_id'}; + @templates = GetModificationTemplates( $template_id ); +} + +my @actions = GetModificationTemplateActions( $template_id ); +foreach my $action ( @actions ) { + $action->{'action_delete_field'} = ( $action->{'action'} eq 'delete_field' ); + $action->{'action_update_field'} = ( $action->{'action'} eq 'update_field' ); + $action->{'action_move_field'} = ( $action->{'action'} eq 'move_field' ); + $action->{'action_copy_field'} = ( $action->{'action'} eq 'copy_field' ); + + $action->{'conditional_if'} = ( $action->{'conditional'} eq 'if' ); + $action->{'conditional_unless'} = ( $action->{'conditional'} eq 'unless' ); + + $action->{'conditional_comparison_exists'} = ( $action->{'conditional_comparison'} eq 'exists' ); + $action->{'conditional_comparison_not_exists'} = ( $action->{'conditional_comparison'} eq 'not_exists' ); + $action->{'conditional_comparison_equals'} = ( $action->{'conditional_comparison'} eq 'equals' ); + $action->{'conditional_comparison_not_equals'} = ( $action->{'conditional_comparison'} eq 'not_equals' ); +} + +$template->param( + TemplatesLoop => \@templates, + ActionsLoop => \@actions, + + template_id => $template_id, +); + +output_html_with_http_headers $cgi, $cookie, $template->output; diff --git a/tools/stage-marc-import.pl b/tools/stage-marc-import.pl index fbb5365699..86e5bbc2b3 100755 --- a/tools/stage-marc-import.pl +++ b/tools/stage-marc-import.pl @@ -41,6 +41,7 @@ use C4::ImportBatch; use C4::Matcher; use C4::UploadedFile; use C4::BackgroundJob; +use Koha::MarcModificationTemplates; my $input = new CGI; my $dbh = C4::Context->dbh; @@ -57,6 +58,8 @@ my $item_action = $input->param('item_action'); my $comments = $input->param('comments'); my $record_type = $input->param('record_type'); my $encoding = $input->param('encoding'); +my $marc_modification_template = $input->param('marc_modification_template_id'); + my ($template, $loggedinuser, $cookie) = get_template_and_user({template_name => "tools/stage-marc-import.tmpl", query => $input, @@ -131,7 +134,7 @@ if ($completedJobID) { } # FIXME branch code - my ($batch_id, $num_valid, $num_items, @import_errors) = BatchStageMarcRecords($record_type, $encoding, $marcrecord, $filename, $comments, '', $parse_items, 0, 50, staging_progress_callback($job, $dbh)); + my ($batch_id, $num_valid, $num_items, @import_errors) = BatchStageMarcRecords($record_type, $encoding, $marcrecord, $filename, $marc_modification_template, $comments, '', $parse_items, 0, 50, staging_progress_callback($job, $dbh)); $dbh->commit(); @@ -180,6 +183,8 @@ if ($completedJobID) { matcher_code => $matcher_code, import_batch_id => $batch_id ); + + } } else { @@ -189,6 +194,10 @@ if ($completedJobID) { } my @matchers = C4::Matcher::GetMatcherList(); $template->param(available_matchers => \@matchers); + + my @templates = GetModificationTemplates(); + $template->param( MarcModificationTemplatesLoop => \@templates ); + } output_html_with_http_headers $input, $cookie, $template->output; -- 2.39.5