Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'Bug4247' into ptfs-master

Conflicts:

	cataloguing/additem.pl
	koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tmpl
  • Loading branch information...
commit d5b3f30b5b5ca2c24a6434c8a647da46f0d0421a 2 parents 73c33d7 + 3a02952
J. David Bavousett authored
View
381 C4/Form/AddItem.pm
@@ -0,0 +1,381 @@
+package C4::Form::AddItem;
+
+# Copyright 2009 Jesse Weaver
+#
+# 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., 59 Temple Place,
+# Suite 330, Boston, MA 02111-1307 USA
+
+use strict;
+use warnings;
+
+use CGI;
+use C4::Context;
+use C4::Debug;
+use C4::Dates;
+use C4::ClassSource;
+use C4::Biblio;
+use C4::Branch qw( GetBranches );
+use C4::Koha qw( subfield_is_koha_internal_p ); # XXX subfield_is_koha_internal_p
+use MARC::Record;
+use MARC::File::XML;
+
+=head1 NAME
+
+C4::Form::AddItem - manage item values input form
+
+=head1 SYNOPSIS
+
+In script:
+
+ use C4::Form::AddItem;
+ C4::Form::AddItem::set_form_values( $existing_values, $template );
+
+In HTML template:
+
+ <!-- TMPL_INCLUDE NAME="item-fields.inc" -->
+
+=head1 DESCRIPTION
+
+This module manages the add item screen used in the import profiles
+functionality of the stage-marc-import.pl tool. It is used both by the tool
+itself and the service that returns existing item definitions for a profile.
+
+=head1 FUNCTIONS
+
+=head2 handle_form_action
+
+ C4::Form::MessagingPreferences::handle_form_action( $input, { categorycode => 'CPL' }, $template );
+
+Processes CGI parameters and updates the target patron or patron category's
+preferences.
+
+C<$input> is the CGI query object.
+
+C<$target_params> is a hashref containing either a C<categorycode> key or a C<borrowernumber> key
+identifying the patron or patron category whose messaging preferences are to be updated.
+
+C<$template> is the HTML::Template::Pro object for the response; this routine
+adds a settings_updated template variable.
+
+=cut
+
+sub get_item_record {
+ my ( $input, $frameworkcode, $item_index, $itemnumber ) = @_;
+ my $dbh = C4::Context->dbh;
+ my @tags = $input->param( "tag_$item_index" );
+ my @subfields = $input->param( "subfield_$item_index" );
+ my @values = $input->param( "field_value_$item_index" );
+ # build indicator hash.
+ my @ind_tag = $input->param( "ind_tag_$item_index" );
+ my @indicator = $input->param( "indicator_$item_index" );
+ # my $itemnumber = $input->param( 'itemnumber' );
+ my $xml = TransformHtmlToXml( \@tags, \@subfields, \@values, \@indicator, \@ind_tag, 'ITEM' );
+ my @params = $input->param();
+ my $itemtosave=MARC::Record::new_from_xml( $xml, 'UTF-8' );
+ if ( !$itemnumber && C4::Context->preference( 'autoBarcode' ) eq 'incremental' ) {
+ my ( $tagfield, $tagsubfield ) = &GetMarcFromKohaField( "items.barcode", $frameworkcode );
+ unless ( $itemtosave->field( $tagfield )->subfield( $tagsubfield ) ) {
+ my $sth_barcode = $dbh->prepare( "select max( abs( barcode ) ) from items" );
+ $sth_barcode->execute;
+ my ( $newbarcode ) = $sth_barcode->fetchrow;
+ $newbarcode++;
+ # OK, we have the new barcode, now create the entry in MARC record
+ my $fieldItem = $itemtosave->field( $tagfield );
+ $itemtosave->delete_field( $fieldItem );
+ $fieldItem->add_subfields( $tagsubfield => $newbarcode );
+ $itemtosave->insert_fields_ordered( $fieldItem );
+ }
+ }
+ # MARC::Record builded => now, record in DB
+ # warn "R: ".$record->as_formatted;
+ # check that the barcode don't exist already
+ my $addedolditem = TransformMarcToKoha( $dbh, $itemtosave );
+ my $exist_itemnumber = get_item_from_barcode( $addedolditem->{'barcode'} );
+ return ( $itemtosave, ( $exist_itemnumber && $exist_itemnumber != $itemnumber ) );
+}
+
+sub get_all_items {
+ my ( $input, $frameworkcode ) = @_;
+
+ my @items = $input->param( 'items' );
+
+ return map { my ($item_record, $not_unique) = get_item_record( $input, $frameworkcode, $_ ); $item_record } @items;
+}
+
+=head2 set_form_values
+
+ C4::Form::MessagingPreferences::set_form_value( { borrowernumber => 51 }, $template );
+
+Retrieves the messaging preferences for the specified patron or patron category
+and fills the corresponding template variables.
+
+C<$target_params> is a hashref containing either a C<categorycode> key or a C<borrowernumber> key
+identifying the patron or patron category.
+
+C<$template> is the HTML::Template::Pro object for the response.
+
+=cut
+
+=head2 get_form_values
+
+ C4::Form::AddItem::get_form_values( $item_index, $existing_record );
+
+Creates the item addition form, and returns an arrayref that can be used in a
+template.
+
+C<$item_index> The index, from 0, of the item ( used to distinguish multiple
+forms, like on the import screen )
+
+C<$existing_record> If basing this on an existing item/created item, this
+should be the relevant MARC blob for that item.
+
+=cut
+
+sub get_form_values {
+ my ( $tagslib, $item_index, $options ) = @_;
+ $options ||= { };
+ $options = {
+ biblio => MARC::Record->new(),
+ frameworkcode => '',
+ omit => [],
+ allow_repeatable => 1,
+ %$options
+ };
+ my $dbh = C4::Context->dbh;
+ my @loop_data =( );
+ my $i=0;
+ my $today_iso = C4::Dates->today( 'iso' );
+ my $authorised_values_sth = $dbh->prepare( "SELECT authorised_value,lib FROM authorised_values WHERE category=? ORDER BY lib" );
+
+ my $onlymine = C4::Context->preference( 'IndependantBranches' ) &&
+ C4::Context->userenv &&
+ C4::Context->userenv->{flags} % 2 == 0 &&
+ C4::Context->userenv->{branch};
+ my $branches = GetBranches( $onlymine ); # build once ahead of time, instead of multiple times later.
+
+ foreach my $tag ( sort keys %{$tagslib} ) {
+ # loop through each subfield
+ foreach my $subfield ( sort keys %{$tagslib->{$tag}} ) {
+ next if subfield_is_koha_internal_p( $subfield );
+ my $subfieldlib = $tagslib->{$tag}->{$subfield};
+ next if ( $subfieldlib->{'tab'} ne "10" );
+ next if ( $subfieldlib->{'kohafield'} && $options->{'omit'} && grep( { $_ eq $subfieldlib->{'kohafield'} } @{ $options->{'omit'} } ) );
+ my %subfield_data;
+
+ my $index_subfield = int( rand( 1000000 ) );
+ if ( $subfield eq '@' ){
+ $subfield_data{id} = "tag_".$tag."_subfield_00_".$index_subfield;
+ } else {
+ $subfield_data{id} = "tag_".$tag."_subfield_".$subfield."_".$index_subfield;
+ }
+ $subfield_data{item_index} = $item_index;
+ $subfield_data{tag} = $tag;
+ $subfield_data{subfield} = $subfield;
+ $subfield_data{random} = int( rand( 1000000 )); # why do we need 2 different randoms?
+ # $subfield_data{marc_lib} = $tagslib->{$tag}->{$subfield}->{lib};
+ $subfield_data{marc_lib} ="<span id=\"error$i\" title=\"".$subfieldlib->{lib}."\">".$subfieldlib->{lib}."</span>";
+ $subfield_data{mandatory} = $subfieldlib->{mandatory};
+ $subfield_data{repeatable} = $subfieldlib->{repeatable} && $options->{'allow_repeatable'};
+ my ( $indicator, $value ) = ( '', '' );
+ ( $indicator, $value ) = _find_value( $tag,$subfield, $options->{'item'} ) if ( $options->{'item'} );
+ $value =~ s/"/&quot;/g;
+ unless ( $value ) {
+ $value = $subfieldlib->{defaultvalue} || '';
+ # get today date & replace YYYY, MM, DD if provided in the default value
+ my ( $year, $month, $day ) = split '-', $today_iso;
+ $value =~ s/YYYY/$year/g;
+ $value =~ s/MM/$month/g;
+ $value =~ s/DD/$day/g;
+ }
+ $subfield_data{visibility} = "display:none;" if ( ($subfieldlib->{hidden} > 4 ) || ( $subfieldlib->{hidden} < -4 ));
+ # testing branch value if IndependantBranches.
+ my $pref_itemcallnumber = C4::Context->preference( 'itemcallnumber' );
+ if ( !$value && $subfieldlib->{kohafield} eq 'items.itemcallnumber' && $pref_itemcallnumber ) {
+ my $CNtag = substr( $pref_itemcallnumber, 0, 3 );
+ my $CNsubfield = substr( $pref_itemcallnumber, 3, 1 );
+ my $CNsubfield2 = substr( $pref_itemcallnumber, 4, 1 );
+ my $temp2 = $options->{'biblio'}->field( $CNtag );
+ if ( $temp2 ) {
+ $value = ( $temp2->subfield( $CNsubfield )).' '.( $temp2->subfield( $CNsubfield2 ));
+ #remove any trailing space incase one subfield is used
+ $value =~ s/^\s+|\s+$//g;
+ }
+ }
+
+ my $attributes_no_value = qq( tabindex="1" id="$subfield_data{id}" name="field_value_$item_index" class="input_marceditor" size="67" maxlength="255" );
+ my $attributes = qq( $attributes_no_value value="$value" );
+ if ( $subfieldlib->{authorised_value} ) {
+ my @authorised_values;
+ my %authorised_lib;
+ # builds list, depending on authorised value...
+
+ if ( $subfieldlib->{authorised_value} eq "branches" ) {
+ foreach my $thisbranch ( sort keys %$branches ) {
+ push @authorised_values, $thisbranch;
+ $authorised_lib{$thisbranch} = $branches->{$thisbranch}->{'branchname'};
+ }
+ }
+ elsif ( $subfieldlib->{authorised_value} eq "itemtypes" ) {
+ push @authorised_values, "" unless ( $subfieldlib->{mandatory} );
+ my $sth = $dbh->prepare( "select itemtype,description from itemtypes order by description" );
+ $sth->execute;
+ my $itemtype; # FIXME: double declaration of $itemtype
+ while ( my ( $itemtype, $description ) = $sth->fetchrow_array ) {
+ push @authorised_values, $itemtype;
+ $authorised_lib{$itemtype} = $description;
+ }
+
+ my ( $itemtype_tag, $itemtype_subfield ) = &GetMarcFromKohaField( "biblioitems.itemtype", $options->{'frameworkcode'} );
+ my $itemtype_field = $options->{'biblio'}->field( $itemtype_tag );
+ if ( !$value && $itemtype_field && $itemtype_field->subfield( $itemtype_subfield ) ) {
+ $value = $itemtype_field->subfield( $itemtype_subfield );
+ }
+
+ #---- class_sources
+ }
+ elsif ( $subfieldlib->{authorised_value} eq "cn_source" ) {
+ push @authorised_values, "" unless ( $subfieldlib->{mandatory} );
+
+ my $class_sources = GetClassSources( );
+ my $default_source = C4::Context->preference( "DefaultClassificationSource" );
+
+ foreach my $class_source ( sort keys %$class_sources ) {
+ next unless $class_sources->{$class_source}->{'used'} or
+ ( $value and $class_source eq $value ) or
+ ( $class_source eq $default_source );
+ push @authorised_values, $class_source;
+ $authorised_lib{$class_source} = $class_sources->{$class_source}->{'description'};
+ }
+ $value = $default_source unless ( $value );
+
+ #---- "true" authorised value
+ }
+ else {
+ push @authorised_values, "" unless ( $subfieldlib->{mandatory} );
+ $authorised_values_sth->execute( $subfieldlib->{authorised_value} );
+ while ( my ( $value, $lib ) = $authorised_values_sth->fetchrow_array ) {
+ push @authorised_values, $value;
+ $authorised_lib{$value} = $lib;
+ }
+ }
+ $subfield_data{marc_value} =CGI::scrolling_list( # FIXME: factor out scrolling_list
+ -name => "field_value_$item_index",
+ -values => \@authorised_values,
+ -default => $value,
+ -labels => \%authorised_lib,
+ -override => 1,
+ -size => 1,
+ -multiple => 0,
+ -tabindex => 1,
+ -id => "tag_".$tag."_subfield_".$subfield."_".$index_subfield,
+ -class => "input_marceditor",
+ );
+ # it's a thesaurus / authority field
+ }
+ elsif ( $subfieldlib->{authtypecode} ) {
+ $subfield_data{marc_value} = "<input type=\"text\" $attributes />
+ <a href=\"#\" class=\"buttonDot\"
+ onclick=\"Dopop( '/cgi-bin/koha/authorities/auth_finder.pl?authtypecode=".$subfieldlib->{authtypecode}."&index=$subfield_data{id}','$subfield_data{id}' ); return false;\" title=\"Tag Editor\">...</a>
+ ";
+ # it's a plugin field
+ }
+ elsif ( $subfieldlib->{value_builder} ) {
+ # opening plugin
+ my $plugin = C4::Context->intranetdir . "/cataloguing/value_builder/" . $subfieldlib->{'value_builder'};
+ if ( do $plugin ) {
+ my $extended_param = plugin_parameters( $dbh, $options->{'biblio'}, $tagslib, $subfield_data{id}, \@loop_data );
+ my ( $function_name, $javascript ) = plugin_javascript( $dbh, $options->{'biblio'}, $tagslib, $subfield_data{id}, \@loop_data );
+ $subfield_data{marc_value} = qq[<input $attributes
+ onfocus="Focus$function_name( $subfield_data{random}, '$subfield_data{id}' );"
+ onblur=" Blur$function_name( $subfield_data{random}, '$subfield_data{id}' );" />
+ <a href="#" class="buttonDot" onclick="Clic$function_name( '$subfield_data{id}' ); return false;" title="Tag Editor">...</a>
+ $javascript];
+ } else {
+ warn "Plugin Failed: $plugin";
+ $subfield_data{marc_value} = "<input $attributes />"; # supply default input form
+ }
+ }
+ elsif ( $tag eq '' ) { # it's an hidden field
+ $subfield_data{marc_value} = qq( <input type="hidden" $attributes /> );
+ }
+ elsif ( $subfieldlib->{'hidden'} ) { # FIXME: shouldn't input type be "hidden" ?
+ $subfield_data{marc_value} = qq( <input type="text" $attributes /> );
+ }
+ elsif ( length( $value ) > 100
+ or ( C4::Context->preference( "marcflavour" ) eq "UNIMARC" and
+ 300 <= $tag && $tag < 400 && $subfield eq 'a' )
+ or ( C4::Context->preference( "marcflavour" ) eq "MARC21" and
+ 500 <= $tag && $tag < 600 )
+ ) {
+ # oversize field ( textarea )
+ $subfield_data{marc_value} = "<textarea $attributes_no_value>$value</textarea>\n";
+ } else {
+ # it's a standard field
+ $subfield_data{marc_value} = "<input $attributes />";
+ }
+ # $subfield_data{marc_value}="<input type=\"text\" name=\"field_value\">";
+ push ( @loop_data, \%subfield_data );
+ $i++
+ }
+ }
+
+ return \@loop_data;
+}
+
+sub _find_value {
+ my ( $tagfield,$insubfield,$record ) = @_;
+ my $indicator = '';
+ my $result = '';
+ foreach my $field ( $record->field( $tagfield )) {
+ my @subfields = $field->subfields( );
+ foreach my $subfield ( @subfields ) {
+ if ( @$subfield[0] eq $insubfield ) {
+ $result .= @$subfield[1];
+ $indicator = $field->indicator( 1 ).$field->indicator( 2 );
+ }
+ }
+ }
+ return( $indicator,$result );
+}
+
+sub get_item_from_barcode {
+ my ( $barcode )=@_;
+ my $dbh=C4::Context->dbh;
+ my $result;
+ my $rq=$dbh->prepare( "SELECT itemnumber from items where items.barcode=?" );
+ $rq->execute( $barcode );
+ ( $result )=$rq->fetchrow;
+ return( $result );
+}
+
+=head1 TODO
+
+=over 4
+
+=item Generalize into a system of form handler clases
+
+=back
+
+=head1 SEE ALSO
+
+F<tools/stage-marc-import.pl>
+
+=head1 AUTHOR
+
+Jesse Weaver <pianohacker@gmail.com>
+
+=cut
+
+1;
View
207 C4/ImportBatch.pm
@@ -22,6 +22,7 @@ use warnings;
use C4::Context;
use C4::Koha;
+use C4::Dates;
use C4::Biblio;
use C4::Items;
use C4::Charset;
@@ -69,6 +70,11 @@ BEGIN {
SetImportRecordStatus
GetImportRecordMatches
SetImportRecordMatches
+ AddImportProfile
+ GetImportProfile
+ GetImportProfileLoop
+ GetImportProfileItems
+ GetImportProfileSubfieldActions
);
}
@@ -208,6 +214,44 @@ sub AddBiblioToBatch {
my $encoding = shift;
my $z3950random = shift;
my $update_counts = @_ ? shift : 1;
+ my $subfield_actions = @_ ? shift : [];
+
+ foreach my $action (@$subfield_actions) {
+ my @fields = $marc_record->field($action->{'tag'});
+ if ( $action->{'action'} eq 'delete' ) {
+ foreach my $field (@fields) {
+ $marc_record->delete_field($field);
+ }
+ } elsif ( $action->{'action'} eq 'delete_sub' ) {
+ foreach my $field (@fields) {
+ $field->delete_subfield(code => $action->{'subfield'});
+ }
+ } elsif ( $action->{'action'} eq 'delete_match' ) {
+ foreach my $field (@fields) {
+ if ($field->subfield($action->{'subfield'})){
+ my $cmp1 = _normalize_string($field->subfield($action->{'subfield'}));
+ my $cmp2 = _normalize_string($action->{'contents'});
+ if ($cmp1 eq $cmp2){
+ $field->delete_subfield(code => $action->{'subfield'});
+ }
+ }
+ }
+ } elsif ( $action->{'action'} eq 'add_always' ) {
+ $marc_record->insert_grouped_field(MARC::Field->new($action->{'tag'},'','',$action->{'subfield'} => $action->{'contents'}));
+ } elsif ( $action->{'action'} eq 'add' ) {
+ my $found =0;
+ foreach my $field (@fields) {
+ if ($field->subfield($action->{'subfield'})){
+ my $cmp1 = _normalize_string($field->subfield($action->{'subfield'}));
+ my $cmp2 = _normalize_string($action->{'contents'});
+ $found = 1 if ($cmp1 eq $cmp2);
+ }
+ }
+ if (!$found){
+ $marc_record->insert_grouped_field(MARC::Field->new($action->{'tag'},'','',$action->{'subfield'} => $action->{'contents'}));
+ }
+ }
+ }
my $import_record_id = _create_import_record($batch_id, $record_sequence, $marc_record, 'biblio', $encoding, $z3950random);
_add_biblio_fields($import_record_id, $marc_record);
@@ -255,6 +299,8 @@ sub BatchStageMarcRecords {
my $branch_code = shift;
my $parse_items = shift;
my $leave_as_staging = shift;
+ my $added_items = shift;
+ my $subfield_actions = shift;
# optional callback to monitor status
# of job
@@ -268,7 +314,8 @@ sub BatchStageMarcRecords {
}
my $batch_id = AddImportBatch('create_new', 'staging', 'batch', $file_name, $comments);
- if ($parse_items) {
+use Data::Dumper; warn Dumper(@$added_items);
+ if ($parse_items || @$added_items) {
SetImportBatchItemAction($batch_id, 'always_add');
} else {
SetImportBatchItemAction($batch_id, 'ignore');
@@ -279,6 +326,8 @@ sub BatchStageMarcRecords {
my $num_items = 0;
# FIXME - for now, we're dealing only with bibs
my $rec_num = 0;
+ my ($barcode_tag, $barcode_subfield) = &GetMarcFromKohaField( "items.barcode", '' );
+ my (undef, $dateaccessioned_subfield) = &GetMarcFromKohaField( "items.dateaccessioned", '' );
foreach my $marc_blob (split(/\x1D/, $marc_records)) {
$marc_blob =~ s/^\s+//g;
$marc_blob =~ s/\s+$//g;
@@ -294,8 +343,17 @@ sub BatchStageMarcRecords {
push @invalid_records, $marc_blob;
} else {
$num_valid++;
- $import_record_id = AddBiblioToBatch($batch_id, $rec_num, $marc_record, $marc_flavor, int(rand(99999)), 0);
- if ($parse_items) {
+ $import_record_id = AddBiblioToBatch($batch_id, $rec_num, $marc_record, $marc_flavor, int(rand(99999)), 0, $subfield_actions);
+ if (@$added_items) {
+ foreach my $item ( @$added_items ) {
+ my $field = $item->field($barcode_tag);
+ $field->add_subfields(
+ $dateaccessioned_subfield => C4::Dates->today()
+ ) if ( !$field->subfield( $dateaccessioned_subfield ) );
+ $marc_record->append_fields($field);
+ }
+ }
+ if ($parse_items || @$added_items) {
my @import_items_ids = AddItemsToImportBiblio($batch_id, $import_record_id, $marc_record, 0);
$num_items += scalar(@import_items_ids);
}
@@ -1245,8 +1303,151 @@ sub SetImportRecordMatches {
}
}
+sub AddImportProfile {
+ my ($description, $matcher_id, $template_id, $overlay_action, $nomatch_action, $parse_items, $item_action, $added_items, $subfield_actions) = @_;
+
+ my $dbh = C4::Context->dbh;
+
+ my $profile_id = $dbh->selectrow_array("SELECT profile_id FROM import_profiles WHERE description = ?", {}, $description);
+
+ my $sth;
+
+ if ($profile_id) {
+ $sth = $dbh->prepare("
+ UPDATE
+ import_profiles
+ SET matcher_id = ?, template_id = ?, overlay_action = ?, nomatch_action = ?, parse_items = ?, item_action = ?
+ WHERE profile_id = ?
+ ");
+
+ $sth->execute($matcher_id, $template_id, $overlay_action, $nomatch_action, $parse_items, $item_action, $profile_id);
+ $dbh->do("
+ DELETE
+ FROM import_profile_added_items
+ WHERE profile_id = ?
+ ", {}, $profile_id);
+ $dbh->do("
+ DELETE
+ FROM import_profile_subfield_actions
+ WHERE profile_id = ?
+ ", {}, $profile_id);
+ } else {
+ $sth = $dbh->prepare("
+ INSERT
+ INTO import_profiles(description, matcher_id, template_id, overlay_action, nomatch_action, parse_items, item_action)
+ VALUES(?, ?, ?, ?, ?, ?, ?)
+ ");
+
+ $sth->execute($description, $matcher_id, $template_id, $overlay_action, $nomatch_action, $parse_items, $item_action);
+ $profile_id = $dbh->{mysql_insertid};
+ }
+
+ $sth = $dbh->prepare("
+ INSERT
+ INTO import_profile_added_items(profile_id, marcxml)
+ VALUES(?, ?)
+ ");
+
+ foreach my $item (@$added_items) {
+ $sth->execute($profile_id, $item->as_xml());
+ }
+
+ $sth = $dbh->prepare("
+ INSERT
+ INTO import_profile_subfield_actions(profile_id, tag, subfield, action, contents)
+ VALUES(?, ?, ?, ?, ?)
+ ");
+
+ foreach my $action (@$subfield_actions) {
+ $sth->execute($profile_id, $action->{'tag'}, $action->{'subfield'}, $action->{'action'}, $action->{'contents'});
+ }
+}
+
+sub GetImportProfile {
+ my $profile_id = shift;
+
+ my $dbh = C4::Context->dbh;
+
+ my $profile = $dbh->selectrow_hashref( "
+ SELECT
+ description, matcher_id, template_id, overlay_action, nomatch_action, parse_items, item_action
+ FROM import_profiles
+ WHERE profile_id = ?
+ ", {}, $profile_id );
+}
+
+sub GetImportProfileLoop {
+ my $dbh = C4::Context->dbh;
+
+ my $results = $dbh->selectall_arrayref( "
+ SELECT
+ import_profiles.profile_id, description, matcher_id, template_id, overlay_action, nomatch_action, parse_items, item_action, COUNT( marcxml ) AS added_items, ip_actions.tag, ip_actions.subfield
+ FROM import_profiles
+ LEFT JOIN import_profile_added_items AS ip_items ON ( import_profiles.profile_id = ip_items.profile_id )
+ LEFT JOIN import_profile_subfield_actions AS ip_actions ON ( import_profiles.profile_id = ip_actions.profile_id )
+ GROUP BY import_profiles.profile_id, ip_actions.tag, ip_actions.subfield
+ ", { Slice => {} } );
+ return [] unless ( @$results );
+
+ my @profiles;
+ my $current_profile;
+
+ foreach my $result ( @$results ) {
+ if ( $current_profile && $current_profile->{'profile_id'} == $result->{'profile_id'} ) {
+ push @{ $current_profile->{'modified_subfields'} }, { tag => $result->{'tag'}, subfield => $result->{'subfield'} }
+ } else {
+ push @profiles, $result;
+ $current_profile = $result;
+ $current_profile->{'modified_subfields'} = $result->{'tag'} ? [ { tag => $result->{'tag'}, subfield => $result->{'subfield'} } ] : [];
+ }
+ delete $result->{'tag'};
+ delete $result->{'subfield'};
+ }
+
+ return \@profiles;
+}
+
+sub GetImportProfileItems {
+ my ( $profile_id ) = @_;
+ my $dbh = C4::Context->dbh;
+
+ return map { MARC::Record::new_from_xml( $_, 'UTF-8' ) } @{ $dbh->selectcol_arrayref( "
+ SELECT
+ marcxml
+ FROM import_profile_added_items
+ WHERE profile_id = ?
+ ", {}, $profile_id ) };
+}
+
+sub GetImportProfileSubfieldActions {
+ my ( $profile_id ) = @_;
+ my $dbh = C4::Context->dbh;
+
+ return map {
+ +{
+ "action_type_" . $_->{'action_type'} => 1,
+ %$_
+ };
+ } @{ $dbh->selectall_arrayref( "
+ SELECT
+ tag as action_tag, subfield as action_subfield, action as action_type, contents as action_contents
+ FROM import_profile_subfield_actions
+ WHERE profile_id = ?
+ ", { Slice => {} }, $profile_id ) };
+}
# internal functions
+sub _normalize_string {
+ my ($str) = @_;
+ $str = uc $str;
+ $str =~ s/^\s+//;
+ $str =~ s/\s+$//;
+ $str =~ s/\W+$//;
+ $str =~ s/\s+$//;
+ $str =~ s/\s+/_/g;
+ $str =~ s/__/_/g;
+ return $str;
+}
sub _create_import_record {
my ($batch_id, $record_sequence, $marc_record, $record_type, $encoding, $z3950random) = @_;
View
66 cataloguing/additem.pl
@@ -20,15 +20,14 @@
use CGI;
use strict;
+use warnings;
use C4::Auth;
use C4::Output;
use C4::Biblio;
use C4::Items;
use C4::Context;
-use C4::Koha; # XXX subfield_is_koha_internal_p
-use C4::Branch; # XXX subfield_is_koha_internal_p
-use C4::ClassSource;
use C4::Dates;
+use C4::Form::AddItem;
use MARC::File::XML;
@@ -72,8 +71,8 @@ sub set_item_default_location {
my $dbh = C4::Context->dbh;
my $error = $input->param('error');
my $biblionumber = $input->param('biblionumber');
-my $itemnumber = $input->param('itemnumber');
-my $op = $input->param('op');
+my $itemnumber = $input->param('itemnumber') || '';
+my $op = $input->param('op') || '';
my ($template, $loggedinuser, $cookie)
= get_template_and_user({template_name => "cataloguing/additem.tmpl",
@@ -98,15 +97,7 @@ sub set_item_default_location {
#-------------------------------------------------------------------------------
if ($op eq "additem") {
#-------------------------------------------------------------------------------
- # rebuild
- my @tags = $input->param('tag');
- my @subfields = $input->param('subfield');
- my @values = $input->param('field_value');
- # build indicator hash.
- my @ind_tag = $input->param('ind_tag');
- my @indicator = $input->param('indicator');
- my $xml = TransformHtmlToXml(\@tags,\@subfields,\@values,\@indicator,\@ind_tag, 'ITEM');
- my $record = MARC::Record::new_from_xml($xml, 'UTF-8');
+ my ( $record, $barcode_not_unique ) = C4::Form::AddItem::get_item_record( $input, $frameworkcode, 0 );
# type of add
my $add_submit = $input->param('add_submit');
@@ -114,24 +105,6 @@ sub set_item_default_location {
my $add_multiple_copies_submit = $input->param('add_multiple_copies_submit');
my $number_of_copies = $input->param('number_of_copies');
- # if autoBarcode is set to 'incremental', calculate barcode...
- # NOTE: This code is subject to change in 3.2 with the implemenation of ajax based autobarcode code
- # NOTE: 'incremental' is the ONLY autoBarcode option available to those not using javascript
- if (C4::Context->preference('autoBarcode') eq 'incremental') {
- my ($tagfield,$tagsubfield) = &GetMarcFromKohaField("items.barcode",$frameworkcode);
- unless ($record->field($tagfield)->subfield($tagsubfield)) {
- my $sth_barcode = $dbh->prepare("select max(abs(barcode)) from items");
- $sth_barcode->execute;
- my ($newbarcode) = $sth_barcode->fetchrow;
- $newbarcode++;
- # OK, we have the new barcode, now create the entry in MARC record
- my $fieldItem = $record->field($tagfield);
- $record->delete_field($fieldItem);
- $fieldItem->add_subfields($tagsubfield => $newbarcode);
- $record->insert_fields_ordered($fieldItem);
- }
- }
-
my $addedolditem = TransformMarcToKoha($dbh,$record);
# If we have to add or add & duplicate, we add the item
@@ -207,7 +180,7 @@ sub set_item_default_location {
}
# Checking if the barcode already exists
- $exist_itemnumber = get_item_from_barcode($barcodevalue);
+ $exist_itemnumber = C4::Form::AddItem::get_item_from_barcode($barcodevalue);
}
# Adding the item
@@ -268,22 +241,9 @@ sub set_item_default_location {
} elsif ($op eq "saveitem") {
#-------------------------------------------------------------------------------
# rebuild
- my @tags = $input->param('tag');
- my @subfields = $input->param('subfield');
- my @values = $input->param('field_value');
- # build indicator hash.
- my @ind_tag = $input->param('ind_tag');
- my @indicator = $input->param('indicator');
- # my $itemnumber = $input->param('itemnumber');
- my $xml = TransformHtmlToXml(\@tags,\@subfields,\@values,\@indicator,\@ind_tag,'ITEM');
- my $itemtosave=MARC::Record::new_from_xml($xml, 'UTF-8');
- # MARC::Record builded => now, record in DB
- # warn "R: ".$record->as_formatted;
- # check that the barcode don't exist already
- my $addedolditem = TransformMarcToKoha($dbh,$itemtosave);
- my $exist_itemnumber = get_item_from_barcode($addedolditem->{'barcode'});
- if ($exist_itemnumber && $exist_itemnumber != $itemnumber) {
- push @errors,"barcode_not_unique";
+ my ( $itemtosave, $barcode_not_unique ) = C4::Form::AddItem::get_item_record( $input, $frameworkcode, 0, $itemnumber );
+ if ( $barcode_not_unique ) {
+ push @errors, 'barcode_not_unique';
} else {
my ($oldbiblionumber,$oldbibnum,$oldbibitemnum) = ModItemFromMarc($itemtosave,$biblionumber,$itemnumber);
$itemnumber="";
@@ -323,7 +283,7 @@ sub set_item_default_location {
|| $subf[$i][1];
}
- if (($field->tag eq $branchtagfield) && ($subf[$i][$0] eq $branchtagsubfield) && C4::Context->preference("IndependantBranches")) {
+ if (($field->tag eq $branchtagfield) && ($subf[$i][0] eq $branchtagsubfield) && C4::Context->preference("IndependantBranches")) {
#verifying rights
my $userenv = C4::Context->userenv();
unless (($userenv->{'flags'} == 1) or (($userenv->{'branch'} eq $subf[$i][1]))){
@@ -559,7 +519,11 @@ sub set_item_default_location {
author => $oldrecord->{author},
item_loop => \@item_value_loop,
item_header_loop => \@header_value_loop,
- item => \@loop_data,
+ item => C4::Form::AddItem::get_form_values( $tagslib, 0, {
+ item => $itemrecord,
+ biblio => $temp,
+ frameworkcode => $frameworkcode,
+ }),
itemnumber => $itemnumber,
itemtagfield => $itemtagfield,
itemtagsubfield => $itemtagsubfield,
View
2  koha-tmpl/intranet-tmpl/prog/en/includes/background-job.inc
@@ -72,7 +72,7 @@
backgroundJobProgressTimer = setInterval("updateJobProgress()", 500);
},
error: function(xml, textStatus) {
- alert('Failed to submit form: ' + testStatus);
+ alert('Failed to submit form: ' + textStatus);
}
});
View
14 koha-tmpl/intranet-tmpl/prog/en/includes/import-subfield-action-form.inc
@@ -0,0 +1,14 @@
+<li>
+ <select name="action_type">
+ <!-- TMPL_IF NAME="action_type_delete" --><option value="delete" selected="selected"><!-- TMPL_ELSE --><option value="delete"><!-- /TMPL_IF -->Remove tag:</option>
+ <!-- TMPL_IF NAME="action_type_delete_sub" --><option value="delete_sub" selected="selected"><!-- TMPL_ELSE --><option value="delete_sub"><!-- /TMPL_IF -->Remove subfield:</option>
+ <!-- TMPL_IF NAME="action_type_delete_match" --><option value="delete_match" selected="selected"><!-- TMPL_ELSE --><option value="delete_match"><!-- /TMPL_IF -->Remove match:</option>
+ <!-- TMPL_IF NAME="action_type_add_always" --><option value="add_always" selected="selected"><!-- TMPL_ELSE --><option value="add_always"><!-- /TMPL_IF -->Add:</option>
+ <!-- TMPL_IF NAME="action_type_add" --><option value="add" selected="selected"><!-- TMPL_ELSE --><option value="add"><!-- /TMPL_IF -->Add, if not present:</option>
+ </select>
+ tag <input type="text" name="action_tag" value="<!-- TMPL_VAR NAME="action_tag" -->" size="3" maxlength="3" />
+ <span class="action-contents-subfield" style="display: none">subfield <input type="text" name="action_subfield" value="<!-- TMPL_VAR NAME="action_subfield" -->" size="1" maxlength="1" /></span>
+ <span class="action-contents-text" style="display: none"> with contents <input type="text" name="action_contents" value="" size="20" /></span>
+ <input type="button" class="remove-action" value="-" />
+ <input type="button" class="new-action" value="+" />
+</li>
View
15 koha-tmpl/intranet-tmpl/prog/en/includes/item-fields.inc
@@ -0,0 +1,15 @@
+<!-- TMPL_LOOP NAME="item" -->
+ <li style="<!-- TMPL_VAR NAME='visibility' -->"><div class="subfield_line" id="subfield<!-- TMPL_VAR NAME='tag' --><!-- TMPL_VAR NAME='subfield' --><!-- TMPL_VAR name="random" -->">
+
+ <label><!-- TMPL_VAR NAME="subfield" --> - <!-- TMPL_IF name="mandatory" --><b><!-- /TMPL_IF --><!-- TMPL_VAR NAME="marc_lib" --><!-- TMPL_IF name="mandatory" --> *</b><!-- /TMPL_IF --></label>
+ <input type="hidden" name="indicator_<!-- TMPL_VAR NAME="item_index" -->" value=" " />
+ <!-- TMPL_VAR NAME="marc_value" -->
+ <input type="hidden" name="tag_<!-- TMPL_VAR NAME="item_index" -->" value="<!-- TMPL_VAR NAME="tag" -->" />
+ <input type="hidden" name="subfield_<!-- TMPL_VAR NAME="item_index" -->" value="<!-- TMPL_VAR NAME="subfield" -->" />
+ <input type="hidden" name="mandatory_<!-- TMPL_VAR NAME="item_index" -->" value="<!-- TMPL_VAR NAME="mandatory" -->" />
+ <!-- TMPL_IF NAME="repeatable" -->
+ <span class="buttonPlus" onclick="CloneSubfield('subfield<!-- TMPL_VAR NAME='tag' --><!-- TMPL_VAR NAME='subfield' --><!-- TMPL_VAR name="random" -->')">+</span>
+ <!-- /TMPL_IF -->
+
+ </div></li>
+<!-- /TMPL_LOOP -->
View
10 koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tmpl
@@ -270,8 +270,7 @@ function set_to_today(id, force) {
<!-- /TMPL_IF -->
</ol>
</fieldset>
- <input type="hidden" name="indicator" value=" " />
- <input type="hidden" name="indicator" value=" " />
+ <input type="hidden" name="indicator_0" value=" " />
<input type="hidden" name="itemnumber" value="<!-- TMPL_VAR NAME="itemnumber" -->" />
<fieldset class="action"> <!-- TMPL_IF name="opisadd" -->
@@ -292,10 +291,17 @@ function set_to_today(id, force) {
</span>
<!-- TMPL_ELSE -->
+<<<<<<< HEAD:koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tmpl
<input type="hidden" name="tag" value="<!-- TMPL_VAR NAME="itemtagfield" -->" />
<input type="hidden" name="subfield" value="<!-- TMPL_VAR NAME="itemtagsubfield" -->" />
<input type="hidden" name="field_value" value="<!-- TMPL_VAR NAME="itemnumber" -->" />
<input type="submit" value="Save Changes" onclick="return Check(this.form)" />
+=======
+ <input type="hidden" name="tag_0" value="<!-- TMPL_VAR NAME="itemtagfield" -->" />
+ <input type="hidden" name="subfield_0" value="<!-- TMPL_VAR NAME="itemtagsubfield" -->" />
+ <input type="hidden" name="field_value_0" value="<!-- TMPL_VAR NAME="itemnumber" -->" />
+ <input type="submit" value="Save Changes" onclick="return Check(this.form)" />
+>>>>>>> Bug4247:koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tmpl
<!-- /TMPL_IF --></fieldset>
</form>
View
4 koha-tmpl/intranet-tmpl/prog/en/modules/tools/pieces/import-profile-actions.tmpl
@@ -0,0 +1,4 @@
+<!-- TMPL_LOOP NAME="actions" -->
+<!-- TMPL_INCLUDE NAME="import-subfield-action-form.inc" -->
+<!-- /TMPL_LOOP -->
+
View
6 koha-tmpl/intranet-tmpl/prog/en/modules/tools/pieces/import-profile-items.tmpl
@@ -0,0 +1,6 @@
+<!-- TMPL_LOOP NAME="items" -->
+<ol id="item-<!-- TMPL_VAR NAME="item_index" -->" class="item">
+ <!-- TMPL_INCLUDE NAME="item-fields.inc" -->
+</ol>
+<input type="hidden" name="items" value="<!-- TMPL_VAR NAME="item_index" -->" />
+<!-- /TMPL_LOOP -->
View
263 koha-tmpl/intranet-tmpl/prog/en/modules/tools/stage-marc-import.tmpl
@@ -19,13 +19,224 @@ function CheckForm(f) {
if ($("#fileToUpload").value == '') {
alert('Please upload a file first.');
} else {
+ // This hack is required due to an odd jQuery/AJAX/Firefox Heisenbug where empty fields don't get submitted
+ $( ':input[name=items]' ).each( function () {
+ var item = this.value;
+ var field_values = f['field_value_' + item];
+ for ( var i = field_values.length - 1; i; i-- ) {
+ if ( field_values[i].value == '' ) {
+ $( field_values[i] ).parents( '.subfield_line' ).find( ':input[name$=_' + item + ']' ).attr('disabled', 'disabled');
+ }
+ }
+ } );
return submitBackgroundJob(f);
}
return false;
}
+<!-- TMPL_IF NAME="available_profiles" -->
+
+var available_profiles = {
+ <!-- TMPL_LOOP NAME="available_profiles" -->
+ <!-- TMPL_VAR NAME="profile_id" -->: {
+ matcher_id: "<!-- TMPL_VAR NAME="matcher_id" -->",
+ overlay_action: "<!-- TMPL_VAR NAME="overlay_action" -->",
+ nomatch_action: "<!-- TMPL_VAR NAME="nomatch_action" -->",
+ parse_items: "<!-- TMPL_VAR NAME="parse_items" -->",
+ item_action: "<!-- TMPL_VAR NAME="item_action" -->",
+ added_items: <!-- TMPL_VAR NAME="added_items" -->,
+ modified_subfields: [ <!-- TMPL_LOOP NAME="modified_subfields" -->[ "<!-- TMPL_VAR NAME="tag" -->", "<!-- TMPL_VAR NAME="subfield" -->" ]<!-- TMPL_UNLESS NAME="__last__" -->, <!-- /TMPL_UNLESS--><!-- /TMPL_LOOP --> ]
+ }<!-- TMPL_UNLESS NAME="__last__" -->,<!-- /TMPL_UNLESS -->
+ <!-- /TMPL_LOOP -->
+};
+
+$( document ).ready( function( ){
+ $( '#profile' ).change( function( ){
+ var profile = $( this ).val( );
+
+ if ( !profile ) return;
+
+ profile = available_profiles[profile];
+
+ $( '#matcher' ).val( profile.matcher_id );
+ $( '#overlay_action' ).val( profile.overlay_action );
+ $( '#nomatch_action' ).val( profile.nomatch_action );
+ $( '#parse_items' + ( profile.parse_items ? 'yes' : 'no' ) ).val( ['parse_items'] );
+ $( '#item_action' ).val( profile.item_action );
+ if ( profile.added_items ) {
+ $( '#profile-items-num-added' ).text( profile.added_items );
+ $( '#profile-items-info' ).show();
+ $( '#add-items input[name=include_items_from_profile]' ).val( 1 );
+ } else {
+ $( '#profile-items-info:visible' ).hide();
+ }
+ if ( profile.modified_subfields.length ) {
+ var modified_subfields = [];
+ $.each( profile.modified_subfields, function ( i, subfield ) {
+ modified_subfields.push( subfield[0] + '$' + subfield[1] );
+ } );
+ console.log( modified_subfields );
+ $( '#profile-actions-subfields' ).text( modified_subfields.join( ', ' ) );
+ $( '#profile-actions-info' ).show();
+ $( '#modify-subfields input[name=include_actions_from_profile]' ).val( 1 );
+ } else {
+ $( '#profile-actions-info:visible' ).hide();
+ }
+ } );
+} );
+
+<!-- /TMPL_IF -->
+
+function change_type() {
+ if ( this.value == 'delete' ) {
+ $( this ).nextAll( '.action-contents-text' ).eq( 0 ).hide();
+ $( this ).nextAll( '.action-contents-subfield' ).eq( 0 ).hide();
+ } else if ( this.value == 'delete_sub' ){
+ $( this ).nextAll( '.action-contents-text' ).eq( 0 ).hide();
+ $( this ).nextAll( '.action-contents-subfield' ).eq( 0 ).show();
+ } else {
+ $( this ).nextAll( '.action-contents-text' ).eq( 0 ).show();
+ $( this ).nextAll( '.action-contents-subfield' ).eq( 0 ).show();
+ }
+}
+
+function verify_tag() {
+ if ( /^[0-9]{3}$/.test( this.value ) ) {
+ $( this ).removeClass( 'alert' );
+ } else {
+ $( this ).addClass( 'alert' );
+ }
+}
+
+function verify_subfield() {
+ if ( /^[0-9a-z]$/.test( this.value ) ) {
+ $( this ).removeClass( 'alert' );
+ } else {
+ $( this ).addClass( 'alert' );
+ }
+}
+
+function remove_action() {
+ $( this ).parent().remove();
+}
+
+function new_action() {
+ var new_row = $( this ).parent().clone();
+
+ bind_subfield_actions( new_row );
+ $( new_row )
+ .find( 'input[type=text]' ).val( '' ).end()
+ .find( 'select' ).val( 'delete' ).change().end()
+ .find( '.remove-action' ).show().end()
+ .insertAfter( $( this ).parent() );
+}
+
+function bind_subfield_actions( selector ) {
+ $( selector )
+ .find( 'select' ).change( change_type ).end()
+ .find( 'input[name=action_tag]' ).keyup( verify_tag ).end()
+ .find( 'input[name=action_subfield]' ).keyup( verify_subfield ).end()
+ .find( '.remove-action' ).click( remove_action ).end()
+ .find( '.new-action' ).click( new_action ).end();
+}
+
+function remove_item() {
+ var parent = $( this ).parents( '.item' );
+ var id = parent.attr( 'id' ).split( '-' )[1];
+
+ $( '#add-items input:hidden[name=items][value=' + id + ']' ).remove();
+ if ( id == 0 ) {
+ parent.hide();
+ } else {
+ parent.remove();
+ }
+}
+
+$( document ).ready( function () {
+ $( '#subfield-actions .remove-action' ).hide();
+ bind_subfield_actions( '#subfield-actions' );
+ $( '#new-item' ).click( function () {
+ if ( $( '#item-0' ).is( ':hidden' ) ) {
+ $( '#item-0' ).show();
+ $( '#add-items' ).append( '<input type="hidden" name="items" value="0" />' );
+ } else {
+ var new_item = $( '#item-0' ).clone();
+
+ var item_id = Math.floor( Math.random() * 100000000 );
+
+ $( new_item ).attr( 'id', 'item-' + item_id ).find( ':text, input:hidden, select' ).attr( 'name', function () {
+ var cur_name = $( this ).attr( 'name').split( '_' );
+ cur_name[cur_name.length - 1] = item_id;
+
+ return cur_name.join( '_' );
+ } );
+
+ $( new_item )
+ .find( ':text' ).val( '' ).end()
+ .find( 'select' ).each( function () { this.selectedIndex = 0 } ).end() // Really need to find a better way of resetting <select>'s
+ .find( '.remove-item' ).click( remove_item ).end()
+ .insertBefore( '#add-item-actions' );
+ $( '#add-items' ).append( '<input type="hidden" name="items" value="' + item_id + '" />' );
+ }
+ } );
+ $( '.remove-item' ).click( remove_item );
+ $( '#profile-items-modify' ).click( function () {
+ $.ajax( {
+ type: 'GET',
+ url: '/cgi-bin/koha/tools/stage-marc-import.pl',
+ dataType: 'html',
+ data: { profile: $( '#profile' ).val(), retrieve: 'profile-items' },
+ success: function ( data ) {
+ $( data )
+ .find( '.remove-item' ).click( remove_item ).end()
+ .insertBefore( '#item-0' );
+ $( '#profile-items-info' ).hide();
+ $( '#modify-subfields input[name=include_items_from_profile]' ).val( 0 );
+ }
+ } );
+ return false;
+ } );
+ $( '#profile-actions-modify' ).click( function () {
+ $.ajax( {
+ type: 'GET',
+ url: '/cgi-bin/koha/tools/stage-marc-import.pl',
+ dataType: 'html',
+ data: { profile: $( '#profile' ).val(), retrieve: 'profile-actions' },
+ success: function ( data ) {
+ var new_actions = $( data );
+ bind_subfield_actions( new_actions );
+ new_actions.appendTo( '#subfield-actions' )
+ .find( 'select' ).change().end();
+ $( '#profile-actions-info' ).hide();
+ $( '#modify-subfields input[name=include_actions_from_profile]' ).val( 0 );
+ }
+ } );
+ return false;
+ } );
+} );
+function set_to_today(id, force) {
+ if (! id) { alert("Bad id " + id + " sent to set_to_today()"); return 0; }
+ if ($("#" + id).val() == '' || $("#" + id).val() == '0000-00-00' || force) {
+ $("#" + id).val("<!-- TMPL_VAR NAME="today_iso" -->");
+ }
+}
//]]>
</script>
+<style type="text/css">
+ <!--
+ .item {
+ border-top: 1px solid gray;
+ margin-top: 5px;
+ }
+ .item:after {
+ content: ".";
+ display: block;
+ height: 0;
+ clear: both;
+ visibility: hidden;
+ }
+ -->
+</style>
</head>
<body>
<!-- TMPL_INCLUDE NAME="header.inc" -->
@@ -43,6 +254,7 @@ function CheckForm(f) {
<!-- TMPL_IF name="uploadmarc" -->
<p>MARC Staging results :</p>
<ul>
+ <!-- TMPL_IF NAME="saved_profile" --><li>Saved settings as profile "<!-- TMPL_VAR NAME="saved_profile" -->"</li><!-- /TMPL_IF -->
<li><!-- TMPL_VAR name="total" --> records in file</li>
<li><!-- TMPL_VAR name="import_errors" --> records not staged because of MARC error</li>
<li><!-- TMPL_VAR name="staged" --> records staged</li>
@@ -88,7 +300,6 @@ function CheckForm(f) {
<form method="post" id="processfile" action="<!-- TMPL_VAR name="SCRIPT_NAME" -->" enctype="multipart/form-data">
<fieldset class="rows">
<input type="hidden" name="uploadedfileid" id="uploadedfileid" value="" />
- <input type="hidden" name="runinbackground" id="runinbackground" value="" />
<input type="hidden" name="completedJobID" id="completedJobID" value="" />
<ol><li>
<label for="comments">Comments about this file: </label>
@@ -106,6 +317,28 @@ function CheckForm(f) {
</li>
</ol></fieldset>
<fieldset class="rows">
+ <legend>Import profiles</legend>
+ <ol>
+ <!-- TMPL_IF NAME="available_profiles" -->
+ <li>
+ <label for="profile">Use import profile:</label>
+ <select name="profile" id="profile">
+ <option value="">--</option>
+ <!-- TMPL_LOOP NAME="available_profiles" -->
+ <option value="<!-- TMPL_VAR NAME="profile_id" -->"><!-- TMPL_VAR NAME="description" --></option>
+ <!-- /TMPL_LOOP -->
+ </select>
+ </li>
+ <!-- /TMPL_IF -->
+ <p>
+ </p>
+ <li>
+ <label for="new_profile_name">Save these settings as an import profile named:</label>
+ <input type="text" name="new_profile_name" id="new_profile_name" value="" />
+ </li>
+ </ol>
+ </fieldset>
+ <fieldset class="rows">
<legend>Look for existing records in catalog?</legend>
<ol><li><label for="matcher">Record matching rule:</label>
<select name="matcher" id="matcher">
@@ -142,6 +375,34 @@ function CheckForm(f) {
</li>
</ol>
</fieldset>
+ <fieldset class="rows" id="add-items">
+ <legend>Add more items to each record?</legend>
+ <ol style>
+ <input type="hidden" name="include_items_from_profile" value="1" />
+ <li><b>NOTE: if you select to add new items here, any item records in the incoming bibliographic record will also be unavoidably added!<br/></b></li></ol>
+ <ol style="display: none" id="profile-items-info">
+ <li>Adding <span id="profile-items-num-added"></span> more item(s), from import profile. <a href="#" id="profile-items-modify">Modify</a></li>
+ </ol>
+ <ol style="display: none" id="item-0" class="item">
+ <!-- TMPL_INCLUDE NAME="item-fields.inc" -->
+ <li><input type="button" class="remove-item" value="Remove this item" /></li>
+ </ol>
+ <ol id="add-item-actions">
+ <li><input type="button" id="new-item" value="New item" /></li>
+ <li><b>If you make changes to this form, and want to save them, be sure to save the profile!</b></li>
+
+ </ol>
+ </fieldset>
+ <fieldset class="rows" id="modify-subfields">
+ <legend>Modify subfields of each record?</legend>
+ <input type="hidden" name="include_actions_from_profile" value="1" />
+ <ol style="display: none" id="profile-actions-info">
+ <li>Modifying <span id="profile-actions-subfields"></span> based on import profile. <a href="#" id="profile-actions-modify">Modify</a></li>
+ </ol>
+ <ol id="subfield-actions" class="action">
+ <!-- TMPL_INCLUDE NAME="import-subfield-action-form.inc" -->
+ </ol>
+ </fieldset>
<fieldset class="action"><input type="button" id="mainformsubmit" onclick="return CheckForm(this.form);" value="Stage for import" /></fieldset>
<div id="jobpanel"><div id="jobstatus">Job progress: <div id="jobprogress"></div> <span id="jobprogresspercent">0</span>%</div>
View
123 tools/stage-marc-import.pl
@@ -40,6 +40,8 @@
use C4::Matcher;
use C4::UploadedFile;
use C4::BackgroundJob;
+use C4::Form::AddItem;
+use C4::Dates;
my $input = new CGI;
my $dbh = C4::Context->dbh;
@@ -55,15 +57,45 @@
my $item_action = $input->param('item_action');
my $comments = $input->param('comments');
my $syntax = $input->param('syntax');
+my $profile = $input->param('profile');
+my $new_profile_name = $input->param('new_profile_name');
+my $retrieve = $input->param('retrieve') || '';
+
+my $template_name = "tools/stage-marc-import.tmpl";
+if ( $retrieve eq 'profile-items' ) {
+ $template_name = 'tools/pieces/import-profile-items.tmpl';
+} elsif ( $retrieve eq 'profile-actions' ) {
+ $template_name = 'tools/pieces/import-profile-actions.tmpl';
+}
+
my ($template, $loggedinuser, $cookie)
- = get_template_and_user({template_name => "tools/stage-marc-import.tmpl",
+ = get_template_and_user({template_name => $template_name,
query => $input,
type => "intranet",
- authnotrequired => 0,
+ authnotrequired => 1,
flagsrequired => {tools => 'stage_marc_import'},
debug => 1,
});
+my $tagslib = &GetMarcStructure(1, ''); # Assuming default framework
+
+if ( $retrieve ) {
+ if ( $retrieve eq 'profile-items' ) {
+ $template->param( items => [ map {
+ my $item_index = int(rand(10000000));
+ +{ item_index => $item_index, item => C4::Form::AddItem::get_form_values( $tagslib, $item_index, {
+ item => $_,
+ omit => [ 'items.barcode' ],
+ allow_repeatable => 0,
+ } ) };
+ } GetImportProfileItems( $profile ) ] );
+ } elsif ( $retrieve eq 'profile-actions' ) {
+ $template->param( actions => [ GetImportProfileSubfieldActions( $profile ) ] );
+ }
+ output_html_with_http_headers $input, $cookie, $template->output;
+ exit;
+}
+
$template->param(SCRIPT_NAME => $ENV{'SCRIPT_NAME'},
uploadmarc => $fileID);
@@ -88,6 +120,30 @@
my $job = undef;
my $staging_callback = sub { };
my $matching_callback = sub { };
+
+ my @additional_items;
+ my @subfield_actions;
+
+ my @added_items = C4::Form::AddItem::get_all_items($input, '');
+
+ if ( $profile ) {
+ if ( $input->param( 'include_items_from_profile' ) && !@added_items) {
+ push @additional_items, GetImportProfileItems( $profile );
+ }
+ if ( $input->param( 'include_actions_from_profile' ) ) {
+ push @subfield_actions, GetImportProfileSubfieldActions( $profile );
+ }
+ }
+
+ push @additional_items, @added_items;
+# push @additional_items, C4::Form::AddItem::get_all_items( $input, '' );
+ push @subfield_actions, get_subfield_actions( $input );
+
+ if ( $new_profile_name ) {
+ $new_profile_name =~ s/^\s+|\s+$//g;
+ AddImportProfile( $new_profile_name, $matcher_id, undef, $overlay_action, $nomatch_action, $parse_items, $item_action, \@additional_items, \@subfield_actions );
+ }
+
if ($runinbackground) {
my $job_size = () = $marcrecord =~ /\035/g;
# if we're matching, job size is doubled
@@ -123,15 +179,16 @@
# if we get here, we're a child that has detached
# itself from Apache
- $staging_callback = staging_progress_callback($job, $dbh);
- $matching_callback = matching_progress_callback($job, $dbh);
+ # $staging_callback = staging_progress_callback($job, $dbh);
+ # $matching_callback = matching_progress_callback($job, $dbh);
}
# FIXME branch code
my ($batch_id, $num_valid, $num_items, @import_errors) = BatchStageMarcRecords($syntax, $marcrecord, $filename,
$comments, '', $parse_items, 0,
- 50, staging_progress_callback($job, $dbh));
+ \@additional_items, \@subfield_actions);
+ # 50, staging_progress_callback($job, $dbh));
$dbh->commit();
my $num_with_matches = 0;
my $checked_matches = 0;
@@ -142,12 +199,17 @@
if (defined $matcher) {
$checked_matches = 1;
$matcher_code = $matcher->code();
- $num_with_matches = BatchFindBibDuplicates($batch_id, $matcher,
- 10, 50, matching_progress_callback($job, $dbh));
+ #$num_with_matches = BatchFindBibDuplicates($batch_id, $matcher,
+ # 10, 50, matching_progress_callback($job, $dbh));
+ $num_with_matches = BatchFindBibDuplicates($batch_id, $matcher);
SetImportBatchMatcher($batch_id, $matcher_id);
SetImportBatchOverlayAction($batch_id, $overlay_action);
SetImportBatchNoMatchAction($batch_id, $nomatch_action);
- SetImportBatchItemAction($batch_id, $item_action);
+ if ( @additional_items) {
+ SetImportBatchItemAction($batch_id, 'always_add');
+ } else {
+ SetImportBatchItemAction($batch_id, $item_action);
+ }
$dbh->commit();
} else {
$matcher_failed = 1;
@@ -165,20 +227,14 @@
matcher_code => $matcher_code,
import_batch_id => $batch_id
};
+
+ $results->{'saved_profile'} = $new_profile_name if ($new_profile_name);
+
if ($runinbackground) {
$job->finish($results);
} else {
- $template->param(staged => $num_valid,
- matched => $num_with_matches,
- num_items => $num_items,
- import_errors => scalar(@import_errors),
- total => $num_valid + scalar(@import_errors),
- checked_matches => $checked_matches,
- matcher_failed => $matcher_failed,
- matcher_code => $matcher_code,
- import_batch_id => $batch_id
- );
- }
+ $template->param($results);
+ }
} else {
# initial form
@@ -186,7 +242,12 @@
$template->param("UNIMARC" => 1);
}
my @matchers = C4::Matcher::GetMatcherList();
- $template->param(available_matchers => \@matchers);
+ $template->param(
+ available_matchers => \@matchers,
+ available_profiles => GetImportProfileLoop(),
+ item => C4::Form::AddItem::get_form_values( $tagslib, 0, { omit => [ 'items.barcode' ], allow_repeatable => 0 } ),
+ today_iso => C4::Dates->today( 'iso' ),
+ );
}
output_html_with_http_headers $input, $cookie, $template->output;
@@ -213,3 +274,25 @@ sub matching_progress_callback {
$dbh->commit();
}
}
+
+sub get_subfield_actions {
+ my ( $input ) = @_;
+
+ my @types = $input->param( 'action_type' );
+ my @tags = $input->param( 'action_tag' );
+ my @subfields = $input->param( 'action_subfield' );
+ my @contents = $input->param( 'action_contents' );
+ my @results;
+
+ foreach my $i ( 0..$#types ) {
+ next unless ( $tags[$i] );
+ push @results, {
+ action => $types[$i],
+ tag => $tags[$i],
+ subfield => $subfields[$i],
+ contents => $contents[$i],
+ };
+ }
+
+ return @results;
+}
Please sign in to comment.
Something went wrong with that request. Please try again.