Bugzilla – Attachment 29921 Details for
Bug 8064
Merge several biblio records
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
[SIGNED-OFF] Bug 8064: Merge several biblios
Bug-8064-Merge-several-biblios.patch (text/plain), 44.21 KB, created by
Julian Maurice
on 2014-07-21 11:33:44 UTC
(
hide
)
Description:
[SIGNED-OFF] Bug 8064: Merge several biblios
Filename:
MIME Type:
Creator:
Julian Maurice
Created:
2014-07-21 11:33:44 UTC
Size:
44.21 KB
patch
obsolete
>From b33adab4fc4a2ec716f42eae935995feb4a08efc Mon Sep 17 00:00:00 2001 >From: Julian Maurice <julian.maurice@biblibre.com> >Date: Tue, 28 May 2013 16:24:53 +0200 >Subject: [PATCH] Bug 8064: Merge several biblios > >This patch improves the existing merging tool by adding possibility to >merge more than 2 biblios. >There is no functional changes: > - Add some biblios to a list > - In the list check some biblios and click on 'Merge selected records' > - Choose the biblio which will be kept, all others will be deleted > - On the next page you have all biblios you chose in tabs (left side > of the screen) and the preview of result (right side) > - Pick some fields or subfields from records that will be deleted or > delete some fields from reference record. > - Click on 'Merge', if there is no errors you are redirected to the > biblio view. > >Added checks for non-repeatable subfields >Added checks for mandatory fields and subfields before submitting the >form. >Added a final report which display deleted records (see syspref >MergeReportFields) >--- > Koha/Util/MARC.pm | 37 +-- > cataloguing/merge.pl | 280 +++++++++++--------- > installer/data/mysql/sysprefs.sql | 1 + > installer/data/mysql/updatedatabase.pl | 11 + > .../prog/en/includes/merge-record.inc | 139 +++++----- > .../en/modules/admin/preferences/cataloguing.pref | 9 + > .../prog/en/modules/cataloguing/merge.tt | 239 +++++++++++++---- > .../prog/en/modules/virtualshelves/shelves.tt | 20 +- > 8 files changed, 459 insertions(+), 277 deletions(-) > >diff --git a/Koha/Util/MARC.pm b/Koha/Util/MARC.pm >index 5d026ee..22774b6 100644 >--- a/Koha/Util/MARC.pm >+++ b/Koha/Util/MARC.pm >@@ -46,16 +46,11 @@ sub createMergeHash { > if ( !defined($tagslib) > || $tagslib->{$fieldtag}->{'@'}->{'tab'} >= 0 ) > { >- push @array, >- { >- field => [ >- { >- tag => $fieldtag, >- key => _createKey(), >- value => $field->data(), >- } >- ] >- }; >+ push @array, { >+ tag => $fieldtag, >+ key => _createKey(), >+ value => $field->data(), >+ }; > } > } > else { >@@ -70,12 +65,11 @@ sub createMergeHash { > && $tagslib->{$fieldtag}->{ @$subfield[0] }->{'tab'} >= 0 ) > ) > { >- push @subfield_array, >- { >+ push @subfield_array, { > subtag => @$subfield[0], > subkey => _createKey(), > value => @$subfield[1], >- }; >+ }; > } > > } >@@ -89,17 +83,12 @@ sub createMergeHash { > && @subfield_array > ) > { >- push @array, >- { >- field => [ >- { >- tag => $fieldtag, >- key => _createKey(), >- indicator1 => $field->indicator(1), >- indicator2 => $field->indicator(2), >- subfield => [@subfield_array], >- } >- ] >+ push @array, { >+ tag => $fieldtag, >+ key => _createKey(), >+ indicator1 => $field->indicator(1), >+ indicator2 => $field->indicator(2), >+ subfield => [@subfield_array], > }; > } > >diff --git a/cataloguing/merge.pl b/cataloguing/merge.pl >index fdac609..36e5970 100755 >--- a/cataloguing/merge.pl >+++ b/cataloguing/merge.pl >@@ -1,6 +1,5 @@ > #!/usr/bin/perl > >- > # Copyright 2009 BibLibre > # Parts Copyright Catalyst IT 2011 > # >@@ -19,8 +18,8 @@ > # 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; FIXME - Bug 2505 >+use Modern::Perl; >+ > use CGI; > use C4::Output; > use C4::Auth; >@@ -33,7 +32,7 @@ use C4::Acquisition qw/ModOrder GetOrdersByBiblionumber/; > use Koha::MetadataRecord; > > my $input = new CGI; >-my @biblionumber = $input->param('biblionumber'); >+my @biblionumbers = $input->param('biblionumber'); > my $merge = $input->param('merge'); > > my @errors; >@@ -54,28 +53,41 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user( > if ($merge) { > > my $dbh = C4::Context->dbh; >- my $sth; > > # Creating a new record from the html code > my $record = TransformHtmlToMarc( $input ); >- my $tobiblio = $input->param('biblio1'); >- my $frombiblio = $input->param('biblio2'); >+ my $ref_biblionumber = $input->param('ref_biblionumber'); >+ @biblionumbers = grep { $_ != $ref_biblionumber } @biblionumbers; >+ >+ # prepare report >+ my @report_records; >+ my $report_fields_str = $input->param('report_fields'); >+ $report_fields_str ||= C4::Context->preference('MergeReportFields'); >+ my @report_fields; >+ foreach my $field_str (split /,/, $report_fields_str) { >+ if ($field_str =~ /(\d{3})([0-9a-z]*)/) { >+ my ($field, $subfields) = ($1, $2); >+ push @report_fields, { >+ tag => $field, >+ subfields => [ split //, $subfields ] >+ } >+ } >+ } > > # Rewriting the leader >- $record->leader(GetMarcBiblio($tobiblio)->leader()); >+ $record->leader(GetMarcBiblio($ref_biblionumber)->leader()); > > my $frameworkcode = $input->param('frameworkcode'); > my @notmoveditems; > > # Modifying the reference record >- ModBiblio($record, $tobiblio, $frameworkcode); >+ ModBiblio($record, $ref_biblionumber, $frameworkcode); > > # Moving items from the other record to the reference record >- # Also moving orders from the other record to the reference record, only if the order is linked to an item of the other record >- my $itemnumbers = get_itemnumbers_of($frombiblio); >- foreach my $itloop ($itemnumbers->{$frombiblio}) { >- foreach my $itemnumber (@$itloop) { >- my $res = MoveItemFromBiblio($itemnumber, $frombiblio, $tobiblio); >+ foreach my $biblionumber (@biblionumbers) { >+ my $itemnumbers = get_itemnumbers_of($biblionumber); >+ foreach my $itemnumber (@{ $itemnumbers->{$biblionumber} }) { >+ my $res = MoveItemFromBiblio($itemnumber, $biblionumber, $ref_biblionumber); > if (not defined $res) { > push @notmoveditems, $itemnumber; > } >@@ -87,137 +99,165 @@ if ($merge) { > push @errors, { code => "CANNOT_MOVE", value => $itemlist }; > } > >- # Moving subscriptions from the other record to the reference record >- my $subcount = CountSubscriptionFromBiblionumber($frombiblio); >- if ($subcount > 0) { >- $sth = $dbh->prepare("UPDATE subscription SET biblionumber = ? WHERE biblionumber = ?"); >- $sth->execute($tobiblio, $frombiblio); >- >- $sth = $dbh->prepare("UPDATE subscriptionhistory SET biblionumber = ? WHERE biblionumber = ?"); >- $sth->execute($tobiblio, $frombiblio); >- >+ my $sth_subscription = $dbh->prepare(" >+ UPDATE subscription SET biblionumber = ? WHERE biblionumber = ? >+ "); >+ my $sth_subscriptionhistory = $dbh->prepare(" >+ UPDATE subscriptionhistory SET biblionumber = ? WHERE biblionumber = ? >+ "); >+ my $sth_serial = $dbh->prepare(" >+ UPDATE serial SET biblionumber = ? WHERE biblionumber = ? >+ "); >+ >+ my $report_header = {}; >+ foreach my $biblionumber ($ref_biblionumber, @biblionumbers) { >+ # build report >+ my $marcrecord = GetMarcBiblio($biblionumber); >+ my %report_record = ( >+ biblionumber => $biblionumber, >+ fields => {}, >+ ); >+ foreach my $field (@report_fields) { >+ my @marcfields = $marcrecord->field($field->{tag}); >+ foreach my $marcfield (@marcfields) { >+ my $tag = $marcfield->tag(); >+ my %subfields; >+ if (scalar @{$field->{subfields}}) { >+ foreach my $subfield (@{$field->{subfields}}) { >+ my @values = $marcfield->subfield($subfield); >+ $report_header->{ $tag . $subfield } = 1; >+ push @{ $report_record{fields}->{$tag . $subfield} }, @values; >+ } >+ } elsif ($field->{tag} gt '009') { >+ my @marcsubfields = $marcfield->subfields(); >+ foreach my $marcsubfield (@marcsubfields) { >+ my ($code, $value) = @$marcsubfield; >+ $report_header->{ $tag . $code } = 1; >+ push @{ $report_record{fields}->{ $tag . $code } }, $value; >+ } >+ } else { >+ $report_header->{ $tag . '@' } = 1; >+ push @{ $report_record{fields}->{ $tag .'@' } }, $marcfield->data(); >+ } >+ } >+ } >+ push @report_records, \%report_record; > } > >- # Moving serials >- $sth = $dbh->prepare("UPDATE serial SET biblionumber = ? WHERE biblionumber = ?"); >- $sth->execute($tobiblio, $frombiblio); >+ foreach my $biblionumber (@biblionumbers) { >+ # Moving subscriptions from the other record to the reference record >+ my $subcount = CountSubscriptionFromBiblionumber($biblionumber); >+ if ($subcount > 0) { >+ $sth_subscription->execute($ref_biblionumber, $biblionumber); >+ $sth_subscriptionhistory->execute($ref_biblionumber, $biblionumber); >+ } > >- # TODO : Moving reserves >+ # Moving serials >+ $sth_serial->execute($ref_biblionumber, $biblionumber); > > # Moving orders (orders linked to items of frombiblio have already been moved by MoveItemFromBiblio) >- my @allorders = GetOrdersByBiblionumber($frombiblio); >- my @tobiblioitem = GetBiblioItemByBiblioNumber ($tobiblio); >+ my @allorders = GetOrdersByBiblionumber($biblionumber); >+ my @tobiblioitem = GetBiblioItemByBiblioNumber ($ref_biblionumber); > my $tobiblioitem_biblioitemnumber = $tobiblioitem [0]-> {biblioitemnumber }; > foreach my $myorder (@allorders) { >- $myorder->{'biblionumber'} = $tobiblio; >+ $myorder->{'biblionumber'} = $ref_biblionumber; > ModOrder ($myorder); > # TODO : add error control (in ModOrder?) > } > >- # Deleting the other record >+ # Deleting the other records > if (scalar(@errors) == 0) { >- # Move holds >- MergeHolds($dbh,$tobiblio,$frombiblio); >- my $error = DelBiblio($frombiblio); >- push @errors, $error if ($error); >+ # Move holds >+ MergeHolds($dbh, $ref_biblionumber, $biblionumber); >+ my $error = DelBiblio($biblionumber); >+ push @errors, $error if ($error); > } >+} > > # Parameters > $template->param( >- result => 1, >- biblio1 => $input->param('biblio1') >+ result => 1, >+ report_records => \@report_records, >+ report_header => $report_header, >+ ref_biblionumber => $input->param('ref_biblionumber') > ); > > #------------------------- > # Show records to merge > #------------------------- > } else { >- my $mergereference = $input->param('mergereference'); >- my $biblionumber = $input->param('biblionumber'); >- >- if (scalar(@biblionumber) != 2) { >- push @errors, { code => "WRONG_COUNT", value => scalar(@biblionumber) }; >- } >- else { >- my $data1 = GetBiblioData($biblionumber[0]); >- my $record1 = GetMarcBiblio($biblionumber[0]); >- >- my $data2 = GetBiblioData($biblionumber[1]); >- my $record2 = GetMarcBiblio($biblionumber[1]); >- >- # Checks if both records use the same framework >- my $frameworkcode1 = &GetFrameworkCode($biblionumber[0]); >- my $frameworkcode2 = &GetFrameworkCode($biblionumber[1]); >- >- >- my $subtitle1 = GetRecordValue('subtitle', $record1, $frameworkcode1); >- my $subtitle2 = GetRecordValue('subtitle', $record2, $frameworkcode1); >- >- if ($mergereference) { >- >- my $framework; >- if ($frameworkcode1 ne $frameworkcode2) { >- $framework = $input->param('frameworkcode') >- or push @errors, "Famework not selected."; >+ my $ref_biblionumber = $input->param('ref_biblionumber'); >+ >+ if ($ref_biblionumber) { >+ my $framework = $input->param('frameworkcode'); >+ $framework //= GetFrameworkCode($ref_biblionumber); >+ >+ # Getting MARC Structure >+ my $tagslib = GetMarcStructure(1, $framework); >+ >+ my $marcflavour = lc(C4::Context->preference('marcflavour')); >+ >+ # Creating a loop for display >+ my @records; >+ foreach my $biblionumber (@biblionumbers) { >+ my $marcrecord = GetMarcBiblio($biblionumber); >+ my $frameworkcode = GetFrameworkCode($biblionumber); >+ my $recordObj = new Koha::MetadataRecord({'record' => $marcrecord, schema => $marcflavour}); >+ my $record = { >+ biblionumber => $biblionumber, >+ record => $marcrecord, >+ frameworkcode => $frameworkcode, >+ display => $recordObj->createMergeHash($tagslib), >+ }; >+ if ($ref_biblionumber and $ref_biblionumber == $biblionumber) { >+ $record->{reference} = 1; >+ $template->param(ref_record => $record); >+ unshift @records, $record; > } else { >- $framework = $frameworkcode1; >+ push @records, $record; > } >- >- # Getting MARC Structure >- my $tagslib = GetMarcStructure(1, $framework); >- >- my $notreference = ($biblionumber[0] == $mergereference) ? $biblionumber[1] : $biblionumber[0]; >- >- # Creating a loop for display >- >- my $recordObj1 = new Koha::MetadataRecord({ 'record' => GetMarcBiblio($mergereference), 'schema' => lc C4::Context->preference('marcflavour') }); >- my $recordObj2 = new Koha::MetadataRecord({ 'record' => GetMarcBiblio($notreference), 'schema' => lc C4::Context->preference('marcflavour') }); >- >- my @record1 = $recordObj1->createMergeHash($tagslib); >- my @record2 = $recordObj2->createMergeHash($tagslib); >- >- # Parameters >- $template->param( >- biblio1 => $mergereference, >- biblio2 => $notreference, >- mergereference => $mergereference, >- record1 => @record1, >- record2 => @record2, >- framework => $framework, >- ); > } >- else { > >+ my ($biblionumbertag) = GetMarcFromKohaField('biblio.biblionumber'); >+ >+ # Parameters >+ $template->param( >+ ref_biblionumber => $ref_biblionumber, >+ records => \@records, >+ ref_record => $records[0], >+ framework => $framework, >+ biblionumbertag => $biblionumbertag, >+ MergeReportFields => C4::Context->preference('MergeReportFields'), >+ ); >+ } else { >+ my @records; >+ foreach my $biblionumber (@biblionumbers) { >+ my $frameworkcode = GetFrameworkCode($biblionumber); >+ my $record = { >+ biblionumber => $biblionumber, >+ data => GetBiblioData($biblionumber), >+ frameworkcode => $frameworkcode, >+ }; >+ push @records, $record; >+ } > # Ask the user to choose which record will be the kept >- $template->param( >- choosereference => 1, >- biblio1 => $biblionumber[0], >- biblio2 => $biblionumber[1], >- title1 => $data1->{'title'}, >- subtitle1 => $subtitle1, >- title2 => $data2->{'title'}, >- subtitle2 => $subtitle2 >+ $template->param( >+ choosereference => 1, >+ records => \@records, >+ ); >+ >+ my $frameworks = getframeworks; >+ my @frameworkselect; >+ foreach my $thisframeworkcode ( keys %$frameworks ) { >+ my %row = ( >+ value => $thisframeworkcode, >+ frameworktext => $frameworks->{$thisframeworkcode}->{'frameworktext'}, > ); >- if ($frameworkcode1 ne $frameworkcode2) { >- my $frameworks = getframeworks; >- my @frameworkselect; >- foreach my $thisframeworkcode ( keys %$frameworks ) { >- my %row = ( >- value => $thisframeworkcode, >- frameworktext => $frameworks->{$thisframeworkcode}->{'frameworktext'}, >- ); >- if ($frameworkcode1 eq $thisframeworkcode){ >- $row{'selected'} = 1; >- } >- push @frameworkselect, \%row; >- } >- $template->param( >- frameworkselect => \@frameworkselect, >- frameworkcode1 => $frameworkcode1, >- frameworkcode2 => $frameworkcode2, >- ); >- } >+ push @frameworkselect, \%row; > } >+ $template->param( >+ frameworkselect => \@frameworkselect, >+ ); > } > } > >@@ -228,11 +268,3 @@ if (@errors) { > > output_html_with_http_headers $input, $cookie, $template->output; > exit; >- >-=head1 FUNCTIONS >- >-=cut >- >-# ------------------------ >-# Functions >-# ------------------------ >diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql >index ed427ea..f8a7001 100644 >--- a/installer/data/mysql/sysprefs.sql >+++ b/installer/data/mysql/sysprefs.sql >@@ -190,6 +190,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` > ('maxoutstanding','5','','maximum amount withstanding to be able make holds','Integer'), > ('maxRecordsForFacets','20',NULL,NULL,'Integer'), > ('maxreserves','50','','Define maximum number of holds a patron can place','Integer'), >+('MergeReportFields','',NULL,'Displayed fields for deleted MARC records after merge','Free'), > ('minPasswordLength','3',NULL,'Specify the minimum length of a patron/staff password','free'), > ('NewItemsDefaultLocation','','','If set, all new items will have a location of the given Location Code ( Authorized Value type LOC )',''), > ('noissuescharge','5','','Define maximum amount withstanding before check outs are blocked','Integer'), >diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl >index 1030454..a691bb9 100755 >--- a/installer/data/mysql/updatedatabase.pl >+++ b/installer/data/mysql/updatedatabase.pl >@@ -8570,6 +8570,17 @@ if ( CheckVersion($DBversion) ) { > SetVersion($DBversion); > } > >+$DBversion = "XXX"; >+if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { >+ $dbh->do(" >+ INSERT INTO systempreferences (variable,value,explanation,options,type) >+ VALUES('MergeReportFields','','Displayed fields for deleted MARC records after merge',NULL,'Free'); >+ "); >+ print "Upgrade to $DBversion done (Add system preference 'MergeReportFields')\n"; >+ SetVersion($DBversion); >+} >+ >+ > =head1 FUNCTIONS > > =head2 TableExists($table) >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/merge-record.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/merge-record.inc >index 81a7cc8..4752515 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/merge-record.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/merge-record.inc >@@ -1,91 +1,102 @@ > [% BLOCK sourcetab %] >- <div id="tabrecord[% recordnumber %]"> >- [% IF ( records ) %] >- >+ <div id="tabrecord[% record.biblionumber %]"> > <div class="record"> >- <ul id="ulrecord[% recordnumber %]"> >- [% FOREACH record IN records %] >- [% FOREACH fiel IN record.field %] >- <li id="k[% fiel.key %]"> >- [% IF (defaultrecord) %] >- <input type="checkbox" checked="checked" class="fieldpick" id="rec_[% recordnumber %]_[% fiel.key %]" /> >- [% ELSE %] >- <input type="checkbox" class="fieldpick" id="rec_[% recordnumber %]_[% fiel.key %]" /> >- [% END %] >- <span class="field">[% fiel.tag %]</span> >+ <ul id="ulrecord[% record.biblionumber %]"> >+ [% FOREACH field IN record.display %] >+ [% IF field.tag != biblionumbertag %] >+ <li id="k[% field.key %]"> >+ [% IF (tabrecord.reference) %] >+ <input type="checkbox" checked="checked" class="fieldpick" id="rec_[% record.biblionumber %]_[% field.key %]" /> >+ [% ELSE %] >+ <input type="checkbox" class="fieldpick" id="rec_[% record.biblionumber %]_[% field.key %]" /> >+ [% END %] >+ <label for="rec_[% record.biblionumber %]_[% field.key %]"><span class="field">[% field.tag %]</span></label> > >- <input type="hidden" name="tag_[% fiel.tag %]_indicator1_[% fiel.key %]" value="[% fiel.indicator1 %]" /> >- <input type="hidden" name="tag_[% fiel.tag %]_indicator2_[% fiel.key %]" value="[% fiel.indicator2 %]" /> >- [% IF ( fiel.value ) %] / [% fiel.value %] >- <input type="hidden" name="tag_[% fiel.tag %]_code_00_[% fiel.key %]" value="00" /> >- <input type="hidden" name="tag_[% fiel.tag %]_subfield_00_[% fiel.key %]" value="[% fiel.value %]" /> >- [% END %] >+ <input type="hidden" name="tag_[% field.tag %]_indicator1_[% field.key %]" value="[% field.indicator1 %]" /> >+ <input type="hidden" name="tag_[% field.tag %]_indicator2_[% field.key %]" value="[% field.indicator2 %]" /> >+ [% IF ( field.value ) %] >+ / [% field.value %] >+ <input type="hidden" name="tag_[% field.tag %]_code_00_[% field.key %]" value="00" /> >+ <input type="hidden" name="tag_[% field.tag %]_subfield_00_[% field.key %]" value="[% field.value %]" /> >+ [% END %] > >- [% IF ( fiel.subfield ) %] >- <ul> >- [% FOREACH subfiel IN fiel.subfield %] >- <li id="k[% subfiel.subkey %]"> >- [% IF (defaultrecord) %] >- <input type="checkbox" checked="checked" class="subfieldpick" id="rec_[% recordnumber %]_[% subfiel.subkey %]" /> >- [% ELSE %] >- <input type="checkbox" class="subfieldpick" id="rec_[% recordnumber %]_[% subfiel.subkey %]" /> >+ [% IF ( field.subfield.size ) %] >+ <ul> >+ [% FOREACH subfield IN field.subfield %] >+ <li id="k[% subfield.subkey %]"> >+ [% IF (tabrecord.reference) %] >+ <input type="checkbox" checked="checked" class="subfieldpick" id="rec_[% record.biblionumber %]_[% subfield.subkey %]" /> >+ [% ELSE %] >+ <input type="checkbox" class="subfieldpick" id="rec_[% record.biblionumber %]_[% subfield.subkey %]" /> >+ [% END %] >+ <label for="rec_[% record.biblionumber %]_[% subfield.subkey %]"><span class="subfield">[% subfield.subtag %]</span> / [% subfield.value %]</label> >+ <input type="hidden" name="tag_[% field.tag %]_code_[% subfield.subtag %]_[% field.key %]_[% subfield.subkey %]" value="[% subfield.subtag %]" /> >+ <input type="hidden" name="tag_[% field.tag %]_subfield_[% subfield.subtag %]_[% subfield.key %]_[% subfield.subkey %]" value="[% subfield.value |html%]" /> >+ </li> >+ [% END %] >+ </ul> > [% END %] >- <span class="subfield">[% subfiel.subtag %]</span> / [% subfiel.value %] >- <input type="hidden" name="tag_[% subfiel.tag %]_code_[% subfiel.subtag %]_[% subfiel.key %]_[% subfiel.subkey %]" value="[% subfiel.subtag %]" /> >- <input type="hidden" name="tag_[% subfiel.tag %]_subfield_[% subfiel.subtag %]_[% subfiel.key %]_[% subfiel.subkey %]" value="[% subfiel.value |html%]" /> > </li> >- [% END %] >- </ul> >+ [% END %] > [% END %] >- [% END %] >- </li> >- [% END %] >- </ul> >+ </ul> > </div><!-- /div.record --> >- [% END %] >- </div><!-- /div#tabrecord[% recordnumber %] --> >+ </div><!-- /div#tabrecordXXX --> > [% END %] >+ > [% BLOCK mergesource %] > <div id="tabs" class="toptabs"> > <h2>Source records</h2> > <ul> >- <li><a href="#tabrecord1">[% recordid1 %]</a></li> >- <li><a href="#tabrecord2">[% recordid2 %]</a></li> >+ [% FOREACH record IN sourcerecords %] >+ <li> >+ <a href="#tabrecord[% record.biblionumber %]"> >+ [% record.biblionumber %] >+ [% IF record.reference %](ref)[% END %] >+ </a> >+ </li> >+ [% END %] > </ul> >- [% PROCESS sourcetab records=record1 recordnumber=1 defaultrecord=1 %] >- [% PROCESS sourcetab records=record2 recordnumber=2 defaultrecord=0 %] >+ [% IF ( sourcerecords.size ) %] >+ [% FOREACH record IN sourcerecords %] >+ [% PROCESS sourcetab tabrecord=record %] >+ [% END %] >+ [% END %] > </div> <!-- // #tabs --> > [% END %] >+ > [% BLOCK mergetarget %] > <div id="result"> > <h2>Destination record</h2> > <div style="border:1px solid #E8E8E8;padding:1em;margin-top:2em;"> > <ul id="resultul"> >- [% FOREACH record IN record1 %] >- [% FOREACH fiel IN record.field %]<li id="k[% fiel.key %]"> >- <span class="field">[% fiel.tag %]</span> >- <input type="hidden" name="tag_[% fiel.tag %]_indicator1_[% fiel.key %]" value="[% fiel.indicator1 %]" /> >- <input type="hidden" name="tag_[% fiel.tag %]_indicator2_[% fiel.key %]" value="[% fiel.indicator2 %]" /> >- [% IF ( fiel.value ) %] / >- [% fiel.value %] >- <input type="hidden" name="tag_[% fiel.tag %]_code_00_[% fiel.key %]" value="00" /> >- <input type="hidden" name="tag_[% fiel.tag %]_subfield_00_[% fiel.key %]" value="[% fiel.value |html%]" /> >+ [% FOREACH field IN ref_record.display %] >+ [% IF field.tag != biblionumbertag %] >+ <li id="k[% field.key %]"> >+ <span class="field">[% field.tag %]</span> >+ <input type="hidden" name="tag_[% field.tag %]_indicator1_[% field.key %]" value="[% field.indicator1 %]" /> >+ <input type="hidden" name="tag_[% field.tag %]_indicator2_[% field.key %]" value="[% field.indicator2 %]" /> >+ [% IF ( field.value ) %] >+ / [% field.value %] >+ <input type="hidden" name="tag_[% field.tag %]_code_00_[% field.key %]" value="00" /> >+ <input type="hidden" name="tag_[% field.tag %]_subfield_00_[% field.key %]" value="[% field.value |html%]" /> > [% END %] > >- [% IF ( fiel.subfield ) %] >- <ul> >- [% FOREACH subfiel IN fiel.subfield %] >- <li id="k[% subfiel.subkey %]"> >- <span class="subfield">[% subfiel.subtag %]</span> / [% subfiel.value %] >- <input type="hidden" name="tag_[% subfiel.tag %]_code_[% subfiel.subtag %]_[% subfiel.key %]_[% subfiel.subkey %]" value="[% subfiel.subtag %]" /> >- <input type="hidden" name="tag_[% subfiel.tag %]_subfield_[% subfiel.subtag %]_[% subfiel.key %]_[% subfiel.subkey %]" value="[% subfiel.value |html%]" /> >- </li> >- [% END %] >- </ul> >+ [% IF ( field.subfield ) %] >+ <ul> >+ [% FOREACH subfield IN field.subfield %] >+ <li id="k[% subfield.subkey %]"> >+ <span class="subfield">[% subfield.subtag %]</span> / [% subfield.value %] >+ <input type="hidden" name="tag_[% field.tag %]_code_[% subfield.subtag %]_[% field.key %]_[% subfield.subkey %]" value="[% subfield.subtag %]" /> >+ <input type="hidden" name="tag_[% field.tag %]_subfield_[% subfield.subtag %]_[% field.key %]_[% subfield.subkey %]" value="[% subfield.value |html%]" /> >+ </li> >+ [% END %] >+ </ul> > [% END %] >- </li>[% END %] >- [% END %] >+ </li> >+ [% END %] >+ [% END %] > </ul> >- </div> >+</div> > </div> <!-- // #result --> > [% END %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref >index cff02f7..e0a5f9a 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref >@@ -191,6 +191,15 @@ Cataloging: > yes: Display > no: "Don't display" > - acquisition details on the biblio detail page. >+ - >+ - pref: MergeReportFields >+ - "fields to display for deleted records after merge" >+ - "<br />example: '001,245ab,600'" >+ - "displays:" >+ - "<ul>" >+ - "<li>value of 001</li>" >+ - "<li>subfields a and b of fields 245</li>" >+ - "<li>all subfields of fields 600</li>" > Importing: > - > - When matching on ISBN with the record import tool, >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/merge.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/merge.tt >index 5ef6c99..0e754ee 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/merge.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/merge.tt >@@ -13,12 +13,76 @@ div#result { margin-top: 1em; } > </style> > <script type="text/javascript"> > //<![CDATA[ >+[% UNLESS (result) %] >+ [% IF (choosereference) %] >+ function changeFramework(fw) { >+ $("#frameworkcode").val(fw); >+ } >+ [% ELSE %] >+ function check_mandatory () { >+ var missing = { >+ 'fields': [], >+ 'subfields': [] >+ }; >+ for (tag in tagslib) { >+ if (tag == '000' || tag == '001') >+ continue; >+ if (tagslib[tag].mandatory == 1) { >+ if ($("#resultul span.field:contains("+ tag +")").length == 0) { >+ missing.fields.push(tag); >+ } >+ } >+ for (subfieldcode in tagslib[tag]) { >+ if (subfieldcode == 'lib' || subfieldcode == 'mandatory' >+ || subfieldcode == 'repeatable' || subfieldcode == 'tab') { >+ continue; >+ } >+ if (tagslib[tag][subfieldcode].mandatory == 1 && tagslib[tag][subfieldcode].tab >= 0) { >+ var fields = $("#resultul span.field:contains("+ tag +")"); >+ $(fields).each(function() { >+ var subfields = $(this).parent().find("span.subfield:contains("+ subfieldcode +")"); >+ if (subfields.length == 0) { >+ missing.subfields.push( { >+ 'tag': tag, >+ 'subfieldcode': subfieldcode >+ } ); >+ } >+ }); >+ } >+ } >+ } >+ return missing; >+ } > > // When submiting the form > function mergeformsubmit() { >- $("ul#ulrecord1").remove(); >- $("ul#ulrecord2").remove(); >-} >+ var missing = check_mandatory(); >+ var alert_msg = ''; >+ var error = 0; >+ if (missing.fields.length > 0) { >+ alert_msg += _("Following required fields are missing:") + "\n"; >+ for (var i in missing.fields) { >+ alert_msg += "\t- " + missing.fields[i] + "\n"; >+ error ++; >+ } >+ alert_msg += "\n"; >+ } >+ if (missing.subfields.length > 0) { >+ alert_msg += _("Following required subfields are missing:") + "\n"; >+ for (var i in missing.subfields) { >+ var subfield = missing.subfields[i]; >+ alert_msg += "\t- " + subfield.tag + "$" + subfield.subfieldcode + "\n"; >+ error ++; >+ } >+ } >+ >+ if (error != 0) { >+ alert(alert_msg); >+ return false; >+ } else { >+ $("#tabs").remove(); >+ } >+ } > > $(document).ready(function(){ > // Getting marc structure via ajax >@@ -29,12 +93,16 @@ $(document).ready(function(){ > > // Creating tabs > $("#tabs").tabs(); >-}); > >+ // Check all checkboxes in first tab, and uncheck all others to avoid >+ // inconsistencies from a page refresh. >+ $('#tabs div#tabrecord[% ref_biblionumber %]').find('input[type="checkbox"]').attr('checked', true); >+ $('#tabs > div:not("#tabrecord[% ref_biblionumber %]")').find('input[type="checkbox"]').removeAttr('checked'); > >-function changeFramework(fw) { >- $("#Frameworks").val(fw); >-} >+}); >+ >+ [% END %] >+[% END %] > > //]]> > </script> >@@ -52,23 +120,62 @@ function changeFramework(fw) { > > <h1>Merging records</h1> > [% IF ( result ) %] >- [% IF ( errors ) %] >- >- [% FOREACH error IN errors %] >- <div class="dialog alert"> >- >+ [% IF ( errors.size ) %] >+ [% FOREACH error IN errors %] >+ <div class="dialog alert"> > [% IF error.code == 'CANNOT_MOVE' %] > The following items could not be moved from the old record to the new one: [% error.value %] > [% ELSE %] > [% error %] > [% END %] >- >- <br />Therefore, the record to be merged has not been deleted.</div> >- [% END %] >+ <br /> >+ Therefore, the record to be merged has not been deleted. >+ </div> >+ [% END %] > > [% ELSE %] >- <script type="text/javascript">window.location.href="/cgi-bin/koha/catalogue/MARCdetail.pl?biblionumber=[% biblio1 %]"</script> >- <p>The merging was successful. <a href="/cgi-bin/koha/catalogue/MARCdetail.pl?biblionumber=[% biblio1 %]">Click here to see the merged record.</a></p> >+ <p>The merge was successful. <a href="/cgi-bin/koha/catalogue/MARCdetail.pl?biblionumber=[% ref_biblionumber %]">Click here to see the merged record.</a></p> >+ <h3>Report</h3> >+ <table> >+ <thead> >+ <tr> >+ <th>Biblionumber</th> >+ [% FOREACH key IN report_header.keys.sort %] >+ [% tag = key.substr(0, 3) %] >+ [% code = key.substr(3, 1) %] >+ [% IF code == '@' %] >+ [% header = tag %] >+ [% ELSE %] >+ [% header = tag _ '$' _ code %] >+ [% END %] >+ <th>[% header %]</th> >+ [% END %] >+ </tr> >+ </thead> >+ <tbody> >+ [% FOREACH record IN report_records %] >+ <tr> >+ <td> >+ [% record.biblionumber %] >+ [% IF loop.first %] >+ (record kept) >+ [% END %] >+ </td> >+ [% FOREACH key IN report_header.keys.sort %] >+ <td> >+ [% values = record.fields.$key %] >+ [% IF values %] >+ [% FOREACH value IN record.fields.$key %] >+ [% value %] >+ [% UNLESS loop.last %]<br />[% END %] >+ [% END %] >+ [% END %] >+ </td> >+ [% END %] >+ </tr> >+ [% END %] >+ </tbody> >+ </table> > [% END %] > > [% ELSE %] >@@ -77,64 +184,82 @@ function changeFramework(fw) { > <p>Please choose which record will be the reference for the merge. The record chosen as reference will be kept, and the other will be deleted.</p> > <form id="mergeform" action="/cgi-bin/koha/cataloguing/merge.pl" method="post"> > <fieldset class="rows"> >- <legend>Merge reference</legend> >- <ol> >- <li class="radio"><input type="radio" value="[% biblio1 %]" checked="checked" id="mergereference1" name="mergereference" onclick="changeFramework('[% frameworkcode1 %]')" /><label for="mergereference1">[% title1 %] [% FOREACH subtitl1 IN subtitle1 %] [% subtitl1.subfield %][% END %] (<a href="/cgi-bin/koha/catalogue/showmarc.pl?id=[% biblio1 %]" title="MARC" rel="gb_page_center[600,500]">[% biblio1 %]</a>)</label></li> >- <li class="radio"><input type="radio" value="[% biblio2 %]" id="mergereference2" name="mergereference" onclick="changeFramework('[% frameworkcode2 %]')" /><label for="mergereference2">[% title2 %] [% FOREACH subtitl2 IN subtitle2 %] [% subtitl2.subfield %][% END %] (<a href="/cgi-bin/koha/catalogue/showmarc.pl?id=[% biblio2 %]" title="MARC" rel="gb_page_center[600,500]">[% biblio2 %]</a>)</label></li> >- >- [% IF frameworkselect %] >- <li><label for="frameworkcode">Using framework:</label> >- <select name="frameworkcode" id="frameworkcode"> >- <option value="Default">Default</option> >- [% FOREACH frameworkcodeloo IN frameworkselect %] >- [% IF ( frameworkcodeloo.selected ) %] >- <option value="[% frameworkcodeloo.value %]" selected="selected"> >- [% ELSE %] >- <option value="[% frameworkcodeloo.value %]"> >- [% END %] >- [% frameworkcodeloo.frameworktext %] >- </option> >- [% END %] >- </select></li> >- [% END %] >-</ol> >+ <legend>Merge reference</legend> >+ <ol> >+ [% FOREACH record IN records %] >+ <li class="radio"> >+ [% IF loop.first %] >+ <input type="radio" value="[% record.biblionumber %]" checked="checked" id="ref_biblionumber[% record.biblionumber %]" name="ref_biblionumber" onclick="changeFramework('[% record.frameworkcode %]')" /> >+ [% ELSE %] >+ <input type="radio" value="[% record.biblionumber %]" id="ref_biblionumber[% record.biblionumber %]" name="ref_biblionumber" onclick="changeFramework('[% record.frameworkcode %]')" /> >+ [% END %] >+ <label for="ref_biblionumber[% record.biblionumber %]"> >+ [% record.data.title %] >+ [% FOREACH subtitle IN record.subtitles %] >+ [% subtitle.subfield %] >+ [% END %] >+ (<a href="/cgi-bin/koha/catalogue/showmarc.pl?id=[% record.biblionumber %]" title="MARC" rel="gb_page_center[600,500]">[% record.biblionumber %]</a>) >+ </label> >+ </li> >+ [% END %] >+ >+ [% IF frameworkselect.size %] >+ <li> >+ <label for="frameworkcode">Using framework:</label> >+ <select name="frameworkcode" id="frameworkcode"> >+ <option value="">Default</option> >+ [% FOREACH frameworkcode IN frameworkselect %] >+ [% IF ( frameworkcode.selected ) %] >+ <option value="[% frameworkcode.value %]" selected="selected"> >+ [% ELSE %] >+ <option value="[% frameworkcode.value %]"> >+ [% END %] >+ [% frameworkcode.frameworktext %] >+ </option> >+ [% END %] >+ </select> >+ </li> >+ [% END %] >+ </ol> > >- <input type="hidden" name="biblionumber" value="[% biblio1 %]" /> >- <input type="hidden" name="biblionumber" value="[% biblio2 %]" /> >- <fieldset class="action"><input type="submit" value="Next" /></fieldset> >+ [% FOREACH record IN records %] >+ <input type="hidden" name="biblionumber" value="[% record.biblionumber %]" /> >+ [% END %] >+ <fieldset class="action"> >+ <input type="submit" value="Next" /> >+ </fieldset> > </fieldset> > </form> > [% ELSE %] >-[% IF ( errors ) %] >+[% IF ( errors.size ) %] > <div class="dialog alert"> >- [% FOREACH error IN errors %] >- <p> >- [% IF error.code == 'WRONG_COUNT' %] >- Number of records provided for merging: [% error.value %]. Currently only 2 records can be merged at a time. >- [% ELSE %] >- [% error %] >- [% END %] >- >- </p> >- [% END %] >+ [% FOREACH error IN errors %] >+ <p>[% error %]</p> >+ [% END %] > </div> > [% ELSE %] > <form id="mergeform" action="/cgi-bin/koha/cataloguing/merge.pl" method="post" onsubmit="return mergeformsubmit()"> > > <div class="yui-g"> > <div class="yui-u first"> >-[% PROCESS mergesource recordid1=biblio1 recordid2=biblio2 %] >+[% PROCESS mergesource sourcerecords=records %] > </div> > <div class="yui-u"> > [% PROCESS mergetarget %] > </div> <!-- .yui-u --> > >-<input type="hidden" name="biblio1" value="[% biblio1 %]" /> >-<input type="hidden" name="biblio2" value="[% biblio2 %]" /> >-<input type="hidden" name="mergereference" value="[% mergereference %]" /> >+<input type="hidden" name="ref_biblionumber" value="[% ref_biblionumber %]" /> >+[% FOREACH record IN records %] >+ <input type="hidden" name="biblionumber" value="[% record.biblionumber %]" /> >+[% END %] > <input type="hidden" name="frameworkcode" value="[% framework %]" /> > >-<fieldset class="action"><input type="submit" name="merge" value="Merge" /></fieldset> >+<fieldset class="action"> >+ <input type="submit" name="merge" value="Merge" /> >+ <label for="report_fields">Fields to display in report:</label> >+ <input type="text" name="report_fields" id="report_fields" value="[% MergeReportFields %]" /> >+ <span class="hint">(Example: "001,245ab,600") >+</fieldset> > </div> > </form> > [% END %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/virtualshelves/shelves.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/virtualshelves/shelves.tt >index 23d815f..57395de 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/virtualshelves/shelves.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/virtualshelves/shelves.tt >@@ -101,14 +101,18 @@ $(document).ready(function(){ > * This function checks if the adequate number of records are checked for merging > */ > function MergeItems() { >- var checkboxes = $("input:checkbox:checked"); >- var nbCheckbox = checkboxes.length; >- if (nbCheckbox != 2) { >- alert(_("Two records must be selected for merging.")); >- } else { >- location.href='/cgi-bin/koha/cataloguing/merge.pl?biblionumber=' + checkboxes[0].value + '&biblionumber=' + checkboxes[1].value; >- } >- return false; >+ var checkboxes = $("input:checkbox:checked"); >+ if (checkboxes.length > 0) { >+ var params = []; >+ $(checkboxes).each(function() { >+ params.push('biblionumber=' + $(this).val()); >+ }); >+ var url = '/cgi-bin/koha/cataloguing/merge.pl?' + params.join('&'); >+ location.href = url; >+ } else { >+ alert(_("You must select at least one record")); >+ } >+ return false; > } > > /** >-- >1.7.10.4
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 8064
:
9498
|
18433
|
18840
|
18923
|
19411
|
19413
|
21351
|
22749
|
23708
|
23709
|
23710
|
24078
|
24079
|
24080
|
26055
|
26056
|
26057
|
26058
|
28726
|
28829
|
28830
|
28831
|
28832
|
28833
|
29324
|
29325
|
29326
|
29327
|
29328
|
29921
|
29922
|
29923
|
29924
|
29925
|
35738
|
35739
|
35740
|
35741
|
35742
|
35900
|
35901
|
35902
|
35903
|
35904
|
35905
|
44633
|
44634
|
44635
|
44636
|
44637
|
44638