Bugzilla – Attachment 21351 Details for
Bug 8064
Merge several biblio records
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 8064: Merge several biblios
Bug-8064-Merge-several-biblios.patch (text/plain), 44.58 KB, created by
Julian Maurice
on 2013-09-23 09:59:00 UTC
(
hide
)
Description:
Bug 8064: Merge several biblios
Filename:
MIME Type:
Creator:
Julian Maurice
Created:
2013-09-23 09:59:00 UTC
Size:
44.58 KB
patch
obsolete
>From d2e51d4c1d2fdce25143b4c0031c8246e30fa6ea 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 | 282 +++++++++++--------- > 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, 460 insertions(+), 278 deletions(-) > >diff --git a/Koha/Util/MARC.pm b/Koha/Util/MARC.pm >index fc3c9f2..5fd9991 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 { >@@ -65,29 +60,23 @@ sub createMergeHash { > if ( !defined($tagslib) > || $tagslib->{$fieldtag}->{ @$subfield[0] }->{'tab'} >= 0 ) > { >- push @subfield_array, >- { >+ push @subfield_array, { > subtag => @$subfield[0], > subkey => _createKey(), > value => @$subfield[1], >- }; >+ }; > } > > } > > if ( !defined($tagslib) || @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 e24b767..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,14 +32,14 @@ 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; > > my ( $template, $loggedinuser, $cookie ) = get_template_and_user( > { >- template_name => "cataloguing/merge.tmpl", >+ template_name => "cataloguing/merge.tt", > query => $input, > type => "intranet", > authnotrequired => 0, >@@ -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 4b9c492..1c25179 100644 >--- a/installer/data/mysql/sysprefs.sql >+++ b/installer/data/mysql/sysprefs.sql >@@ -177,6 +177,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` > ('maxRecordsForFacets','20',NULL,NULL,'Integer'), > ('maxreserves','50','','Define maximum number of holds a patron can place','Integer'), > ('memberofinstitution','0',NULL,'If ON, patrons can be linked to institutions','YesNo'), >+('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 31f494a..e4e618e 100755 >--- a/installer/data/mysql/updatedatabase.pl >+++ b/installer/data/mysql/updatedatabase.pl >@@ -7139,6 +7139,17 @@ if ( CheckVersion($DBversion) ) { > SetVersion ($DBversion); > } > >+$DBversion = "3.13.00.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 96f3603..a112b82 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 >@@ -176,3 +176,12 @@ Cataloging: > - pref: NotesBlacklist > class: multi > - note fields in title notes separator (OPAC record details) and in the description separator (Staff client record details). The fields should appear separated with commas and according with the Koha MARC format (eg 3.. for UNIMARC, 5.. for MARC21) >+ - >+ - 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>" >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 aac163f..07e2945 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