@@ -, +, @@ Bug 5725 : Follow up fixing permissions thanks to Paul Poulain Bug 5725 follow up Owen noticed the batchedit was not working. This was because we made a patch months ago to change the GetBiblio API (the 1st returned arg is useless) This patch is not in main trunk, resulting in the error owen has noticed. This patch goes back to official API (even if it is clumsy : the patch we did does not apply anymore) Bug 5725 : MT #2991 (Feature) Batch biblio modifications This patch add a new feature of batch biblio modifications, it permit to select biblios from basket, and modify fields of them setting Rebased to fix whitespace issues. --- C4/Biblio.pm | 171 ++++++++++++++- koha-tmpl/intranet-tmpl/prog/en/js/basket.js | 6 + .../prog/en/modules/basket/basket.tmpl | 5 + .../prog/en/modules/tools/batchedit.tmpl | 231 ++++++++++++++++++++ tools/batchedit.pl | 222 +++++++++++++++++++ 5 files changed, 623 insertions(+), 12 deletions(-) create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/tools/batchedit.tmpl create mode 100755 tools/batchedit.pl --- a/C4/Biblio.pm +++ a/C4/Biblio.pm @@ -93,6 +93,8 @@ BEGIN { &ModBiblio &ModBiblioframework &ModZebra + + &BatchModField ); # To delete something @@ -376,7 +378,7 @@ sub ModBiblioframework { =head2 DelBiblio - my $error = &DelBiblio($dbh,$biblionumber); + my $error = &DelBiblio($biblionumber); Exported function (core API) for deleting a biblio in koha. Deletes biblio record from Zebra and Koha tables (biblio,biblioitems,items) @@ -1046,9 +1048,14 @@ The MARC record contains both biblio & item data. sub GetMarcBiblio { my $biblionumber = shift; + my $deletedtable = shift; my $dbh = C4::Context->dbh; - my $sth = $dbh->prepare("SELECT marcxml FROM biblioitems WHERE biblionumber=? "); - $sth->execute($biblionumber); + my $strsth = qq{SELECT marcxml FROM biblioitems WHERE biblionumber=?}; + $strsth .= qq{UNION SELECT marcxml FROM deletedbiblioitems WHERE biblionumber=?} if $deletedtable; + my $sth = $dbh->prepare($strsth); + my @params=($biblionumber); + push @params, $biblionumber if ($deletedtable); + $sth->execute(@params); my $row = $sth->fetchrow_hashref; my $marcxml = StripNonXmlChars( $row->{'marcxml'} ); MARC::File::XML->default_record_format( C4::Context->preference('marcflavour') ); @@ -1113,6 +1120,8 @@ sub GetCOinSBiblio { my $isbn = ''; my $issn = ''; my $publisher = ''; + my $place = ''; + my $tpages = ''; if ( C4::Context->preference("marcflavour") eq "UNIMARC" ) { my $fmts6; @@ -1159,24 +1168,70 @@ sub GetCOinSBiblio { $genre = ( $mtx eq 'dc' ) ? "&rft.type=$genre" : "&rft.genre=$genre"; # Setting datas - $aulast = $record->subfield( '700', 'a' ); - $aufirst = $record->subfield( '700', 'b' ); - $oauthors = "&rft.au=$aufirst $aulast"; + + # authors + $aulast = $record->subfield( '700', 'a' ) || ''; + $aufirst = $record->subfield( '700', 'b' ) || ''; + + foreach my $field (qw/700 701/) { + my $author = ''; + $author = $record->subfield($field, 'a') || ''; + $author .= ", " . $record->subfield($field, 'b') if ($author and $record->subfield($field, 'b')); + $author .= " - " . join(' - ', $record->subfield($field, '4')) if ($record->subfield($field, '4')); + $author .= " (" . $record->subfield($field, 'f') . ")" if ($record->subfield($field, 'f')); + + $oauthors .= "&rft.au=$author" if ($author); + } + + foreach my $field (qw/710 711/) { + my $author = ''; + $author = $record->subfield($field, 'a') || ''; + $author .= ", " . $record->subfield($field, 'b') if ($author and $record->subfield($field, 'b')); + $author .= " - " . join(' - ', $record->subfield($field, '4')) if ($record->subfield($field, '4')); + $author .= " (" . $record->subfield($field, 'c') . ")" if ($record->subfield($field, 'c')); + + $oauthors .= "&rft.au=$author" if ($author); + } + # others authors if ( $record->field('200') ) { + for my $au ( $record->field('200')->subfield('f') ) { + $oauthors .= "&rft.au=$au"; + } for my $au ( $record->field('200')->subfield('g') ) { $oauthors .= "&rft.au=$au"; } + } + + # place + $place = join(" - ", $record->subfield('210', 'a')); + $place = "&rtf.place=$place" if ($place); + + # tpages + my $i = 0; + foreach my $field ($record->field('215')) { + $tpages .= " | " if ($i > 0); + $tpages .= join(" - ", $field->subfield('a')); + $tpages .= join(" ; ", $field->subfield('d')); + $tpages .= join(" + ", $field->subfield('e')); + $i++; + } + $tpages = "&rtf.tpages=$tpages" if ($tpages); + + # title + my $btitle = join(' ; ', $record->subfield('200', 'a')); + $btitle .= " : " . join(' : ', $record->subfield('200', 'e')) if ($record->subfield('200', 'e')); + $title = ( $mtx eq 'dc' ) ? "&rft.title=" . $record->subfield( '200', 'a' ) - : "&rft.title=" . $record->subfield( '200', 'a' ) . "&rft.btitle=" . $record->subfield( '200', 'a' ); - $pubyear = $record->subfield( '210', 'd' ); - $publisher = $record->subfield( '210', 'c' ); - $isbn = $record->subfield( '010', 'a' ); - $issn = $record->subfield( '011', 'a' ); + : "&rft.title=" . $record->subfield( '200', 'a' ) . "&rft.btitle=" . $btitle; + $pubyear = $record->subfield( '210', 'd' ) || ''; + $publisher = $record->subfield( '210', 'c' ) || ''; + $isbn = $record->subfield( '010', 'a' ) || ''; + $issn = $record->subfield( '011', 'a' ) || ''; } else { # MARC21 need some improve @@ -1205,7 +1260,7 @@ sub GetCOinSBiblio { } my $coins_value = -"ctx_ver=Z39.88-2004&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3A$mtx$genre$title&rft.isbn=$isbn&rft.issn=$issn&rft.aulast=$aulast&rft.aufirst=$aufirst$oauthors&rft.pub=$publisher&rft.date=$pubyear"; +"ctx_ver=Z39.88-2004&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3A$mtx$genre$title&rft.isbn=$isbn&rft.issn=$issn&rft.aulast=$aulast&rft.aufirst=$aufirst$oauthors&rft.pub=$publisher&rft.date=$pubyear$place$tpages"; $coins_value =~ s/(\ |&[^a])/\+/g; $coins_value =~ s/\"/\"\;/g; @@ -1750,6 +1805,7 @@ sub TransformHtmlToXml { @$values[$i] =~ s/>/>/g; @$values[$i] =~ s/"/"/g; @$values[$i] =~ s/'/'/g; + @$values[$i] = NormalizeString(@$values[$i]); # if ( !utf8::is_utf8( @$values[$i] ) ) { # utf8::decode( @$values[$i] ); @@ -2313,7 +2369,9 @@ sub PrepareItemrecordDisplay { push @authorised_values, $branchcode; $authorised_lib{$branchcode} = $branchname; } + $defaultvalue = C4::Context->userenv->{branch}; } + $defaultvalue = C4::Context->userenv->{branch}; #----- itemtypes } elsif ( $tagslib->{$tag}->{$subfield}->{authorised_value} eq "itemtypes" ) { @@ -3461,6 +3519,95 @@ sub get_biblio_authorised_values { return $authorised_values; } +=head3 BatchModField + + Mod subfields in field record + + returns 1,$record if succeed + returns 0,$record if Action was not processed + returns -1 if no record + returns -2 if no action done on record + +=cut + +sub BatchModField { + my ( $record, $field, $subfield, $action, $condval, $nocond, $repval ) = @_; + + return -1 unless $record; + $condval=NormalizeString($condval); + my $condition=qr/$condval/; + + if($action eq "add"){ + for my $rfield ($record->field($field)){ + $rfield->add_subfields( $subfield => $repval ); + } + return 1; + }elsif($action eq "addfield"){ + my $new_field = MARC::Field->new($field,'','', + $subfield => $repval); + $record->insert_fields_ordered($new_field); + return 1; + } else { + my $done=0; + for my $rfield ($record->field($field)) { + if ($subfield && $subfield ne "@"){ + my @subfields = $rfield->subfields(); + my @subfields_to_add; + foreach my $subf (@subfields) { + if ($subf->[0] eq $subfield){ + $subf->[1]=NormalizeString($subf->[1]); + if ( $action eq "mod" ) { + if ( $nocond ne "true" && $subf->[1] =~ s/$condition/$repval/) { + $done=1; + } + if ($nocond eq "true"){ + $subf->[1] = $repval; + $done=1; + } + } elsif ( $action eq "del" ) { + if ( $subf->[1] =~ m/$condition/ || $nocond eq "true" ) { + $done=1; + next; + } + } + } + push @subfields_to_add,@$subf; + } + if ($done){ + if (@subfields_to_add){ + $rfield->replace_with(MARC::Field->new($rfield->tag,$rfield->indicator(1),$rfield->indicator(2),@subfields_to_add)); + } + else { + my $count= $record->delete_field($rfield); + } + } + } + else { + if ($action eq "del"){ + my $count=$record->delete_field($rfield); + $done=1; + } + else { + if ($field < 10){ + my $value=$record->field($field)->data(); + if ($value=~ s/$condition/$repval/){ + $record->field($field)->update($value); + $done=1; + + } + if ( $nocond eq 'true'){ + $record->field($field)->update($repval); + $done=1; + } + } + } + } + } + return ($done,$record); + } + return -2; +} + 1; __END__ --- a/koha-tmpl/intranet-tmpl/prog/en/js/basket.js +++ a/koha-tmpl/intranet-tmpl/prog/en/js/basket.js @@ -433,4 +433,10 @@ $(document).ready(function(){ if(basketcount){ updateBasket(basketcount); } }); +function batchEdit(){ + var valCookie = readCookie(nameCookie); + var strCookie = nameParam + "=" + valCookie; + var loc = CGIBIN + "tools/batchedit.pl?" + strCookie; + window.opener.location = loc; +} --- a/koha-tmpl/intranet-tmpl/prog/en/modules/basket/basket.tmpl +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/basket/basket.tmpl @@ -86,6 +86,11 @@ function placeHold () { Brief DisplayMore Details +