@@ -, +, @@
a) Create a list.
b) Add two records you would like to (or be willing to) merge
to said list.
c) View said list.
d) Check the checkboxes next to the two records you added.
e) Click "Merge selected records."
f) Choose a merge reference.
g) Choose fields from each record that you want to keep.
h) Click "Merge."
wanted.
prove t/Koha_Record.t t/db_dependent/Koha_Authority.t
---
Koha/Authority.pm | 5 +-
Koha/Record.pm | 115 +++++++++
cataloguing/merge.pl | 74 +-----
.../prog/en/includes/merge-record.inc | 219 +++++++++++++++++
.../prog/en/modules/cataloguing/merge.tt | 264 +--------------------
t/Koha_Record.t | 99 ++++++++
6 files changed, 449 insertions(+), 327 deletions(-)
create mode 100644 Koha/Record.pm
create mode 100644 koha-tmpl/intranet-tmpl/prog/en/includes/merge-record.inc
create mode 100755 t/Koha_Record.t
--- a/Koha/Authority.pm
+++ a/Koha/Authority.pm
@@ -38,9 +38,9 @@ use MARC::Record;
use MARC::File::XML;
use C4::Charset;
-use base qw(Class::Accessor);
+use base qw(Koha::Record);
-__PACKAGE__->mk_accessors(qw( authid authtype record marcflavour ));
+__PACKAGE__->mk_accessors(qw( authid authtype marcflavour ));
=head2 new
@@ -59,6 +59,7 @@ sub new {
return $self;
}
+
=head2 get_from_authid
my $auth = Koha::Authority->get_from_authid($authid);
--- a/Koha/Record.pm
+++ a/Koha/Record.pm
@@ -0,0 +1,115 @@
+package Koha::Record;
+
+# Copyright 2013 C & P Bibliography Services
+#
+# 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 3 of the License, or (at your option) any later
+# version.
+#
+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with Koha; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+=head1 NAME
+
+Koha::Record - base class for MARC records
+
+=head1 SYNOPSIS
+
+ my $record = new Koha::Record({ 'record' => $marcrecord });
+
+=head1 DESCRIPTION
+
+Object-oriented class that encapsulates all records in Koha.
+
+=cut
+
+use strict;
+use warnings;
+use C4::Context;
+use MARC::Record;
+
+use base qw(Class::Accessor);
+
+__PACKAGE__->mk_accessors(qw( record marcflavour ));
+
+
+=head2 createMarcHash
+
+Create a MARC hash for use when merging records.
+
+=cut
+
+sub createMarcHash {
+ my ($self, $tagslib) = @_;
+ my $record = $self->record;
+ my @array;
+ my @fields = $record->fields();
+
+
+ foreach my $field (@fields) {
+ my $fieldtag = $field->tag();
+ if ($fieldtag < 10) {
+ if (!defined($tagslib) || $tagslib->{$fieldtag}->{'@'}->{'tab'} >= 0) {
+ push @array, {
+ field => [
+ {
+ tag => $fieldtag,
+ key => _createKey(),
+ value => $field->data(),
+ }
+ ]
+ };
+ }
+ } else {
+ my @subfields = $field->subfields();
+ my @subfield_array;
+ foreach my $subfield (@subfields) {
+ if (!defined($tagslib) || $tagslib->{$fieldtag}->{@$subfield[0]}->{'tab'} >= 0) {
+ push @subfield_array, {
+ subtag => @$subfield[0],
+ subkey => _createKey(),
+ value => @$subfield[1],
+ };
+ }
+
+ }
+
+ if ((!defined($tagslib) || $tagslib->{$fieldtag}->{'tab'} >= 0) && $fieldtag ne '995' && $fieldtag ne '999') {
+ push @array, {
+ field => [
+ {
+ tag => $fieldtag,
+ key => _createKey(),
+ indicator1 => $field->indicator(1),
+ indicator2 => $field->indicator(2),
+ subfield => [@subfield_array],
+ }
+ ]
+ };
+ }
+
+ }
+ }
+ return [@array];
+
+}
+
+=head2 _createKey
+
+Create a random value to set it into the input name
+
+=cut
+
+sub _createKey {
+ return int(rand(1000000));
+}
+
+1;
--- a/cataloguing/merge.pl
+++ a/cataloguing/merge.pl
@@ -30,6 +30,7 @@ use C4::Serials;
use C4::Koha;
use C4::Reserves qw/MergeHolds/;
use C4::Acquisition qw/ModOrder GetOrdersByBiblionumber/;
+use Koha::Record;
my $input = new CGI;
my @biblionumber = $input->param('biblionumber');
@@ -168,8 +169,12 @@ if ($merge) {
my $notreference = ($biblionumber[0] == $mergereference) ? $biblionumber[1] : $biblionumber[0];
# Creating a loop for display
- my @record1 = _createMarcHash(GetMarcBiblio($mergereference), $tagslib);
- my @record2 = _createMarcHash(GetMarcBiblio($notreference), $tagslib);
+
+ my $recordObj1 = new Koha::Record({ 'record' => GetMarcBiblio($mergereference) });
+ my $recordObj2 = new Koha::Record({ 'record' => GetMarcBiblio($notreference) });
+
+ my @record1 = $recordObj1->createMarcHash($tagslib);
+ my @record2 = $recordObj2->createMarcHash($tagslib);
# Parameters
$template->param(
@@ -231,68 +236,3 @@ exit;
# ------------------------
# Functions
# ------------------------
-sub _createMarcHash {
- my $record = shift;
- my $tagslib = shift;
- my @array;
- my @fields = $record->fields();
-
-
- foreach my $field (@fields) {
- my $fieldtag = $field->tag();
- if ($fieldtag < 10) {
- if ($tagslib->{$fieldtag}->{'@'}->{'tab'} >= 0) {
- push @array, {
- field => [
- {
- tag => $fieldtag,
- key => createKey(),
- value => $field->data(),
- }
- ]
- };
- }
- } else {
- my @subfields = $field->subfields();
- my @subfield_array;
- foreach my $subfield (@subfields) {
- if ($tagslib->{$fieldtag}->{@$subfield[0]}->{'tab'} >= 0) {
- push @subfield_array, {
- subtag => @$subfield[0],
- subkey => createKey(),
- value => @$subfield[1],
- };
- }
-
- }
-
- if ($tagslib->{$fieldtag}->{'tab'} >= 0 && $fieldtag ne '995') {
- push @array, {
- field => [
- {
- tag => $fieldtag,
- key => createKey(),
- indicator1 => $field->indicator(1),
- indicator2 => $field->indicator(2),
- subfield => [@subfield_array],
- }
- ]
- };
- }
-
- }
- }
- return [@array];
-
-}
-
-=head2 CreateKey
-
-Create a random value to set it into the input name
-
-=cut
-
-sub createKey {
- return int(rand(1000000));
-}
-
--- a/koha-tmpl/intranet-tmpl/prog/en/includes/merge-record.inc
+++ a/koha-tmpl/intranet-tmpl/prog/en/includes/merge-record.inc
@@ -0,0 +1,219 @@
+[% BLOCK sourcetab %]
+
+ [% IF ( records ) %]
+
+
+
+ [% FOREACH record IN records %]
+ [% FOREACH fiel IN record.field %]
+
+[% END %]
+[% BLOCK mergejs %]
+ // Creating tabs
+ $("#tabs").tabs();
+
+ // Toggle a field / subfield
+ function toggleField(pField) {
+
+ // Getting the key of the clicked checkbox
+ var ckid = $(pField).attr("id");
+ var tab = ckid.split('_');
+ var source = tab[1]; // From which record the click came from
+ var key = tab[2];
+ var type = $(pField).attr("class");
+
+ // Getting field/subfield
+ var field;
+ var subfield;
+ if (type == "subfieldpick") {
+
+ field = $(pField).parent().parent().parent().find("span.field").text();
+ subfield = $(pField).parent().find("span.subfield").text();
+ } else {
+
+ field = $(pField).parent().find("span.field").text();
+ }
+
+ // If the field has just been checked
+ if (pField.checked) {
+
+ // We check for repeatability
+ var canbeadded = true;
+ if (type == "subfieldpick") {
+ var repeatable = 1;
+ var alreadyexists = 0;
+ if (tagslib[field] && tagslib[field][subfield]) {
+ repeatable = tagslib[field][subfield].repeatable; // Note : we can't use the dot notation here (tagslib.021) because the key is a number
+ // TODO : Checking for subfields
+ }
+ } else {
+ if (tagslib[field]) {
+ repeatable = tagslib[field].repeatable;
+ alreadyexists = $("#resultul span.field:contains(" + field + ")");
+ if (repeatable == 0 && alreadyexists.length != 0) {
+ canbeadded = false;
+ }
+ }
+ }
+ // If the field is not repeatable, we check if it already exists in the result table
+ if (canbeadded == false) {
+ alert(_("The field is non-repeatable and already exists in the destination record. Therefore, you cannot add it."));
+ pField.checked = 0;
+ } else {
+
+ // Cloning the field or subfield we picked
+ var clone = $(pField).parent().clone();
+
+ // Removing the checkboxes from it
+ $(clone).find("input.subfieldpick, input.fieldpick").each(function() {
+ $(this).remove();
+ });
+
+
+ // If we are a subfield
+ if (type == "subfieldpick") {
+ // then we need to find who is our parent field...
+ fieldkey = $(pField).parent().parent().parent().attr("id");
+
+ // Find where to add the subfield
+
+ // First, check if the field is not already in the destination record
+ if ($("#resultul li#" + fieldkey).length > 0) {
+ // If so, we add our field to it
+ $("#resultul li#" + fieldkey + " ul").append(clone);
+ } else {
+ // If not, we add the subfield to the first matching field
+ var where = 0;
+ $("#resultul li span.field").each(function() {
+ if (where == 0 && $(this).text() == field) {
+ where = this;
+ }
+ });
+
+ // If there is no matching field in the destination record
+ if (where == 0) {
+
+ // TODO:
+ // We select the whole field and removing non-selected subfields, instead of...
+
+ // Alerting the user
+ alert(_("This subfield cannot be added: there is no") + " " + field + " " + _("field in the destination record."));
+ pField.checked = false;
+
+ } else {
+ $(where).nextAll("ul").append(clone);
+ }
+
+ }
+
+
+
+ } else {
+ // If we are a field
+ var where = 0;
+ // Find where to add the field
+ $("#resultul li span.field").each(function() {
+ if (where == 0 && $(this).text() > field) {
+ where = this;
+ }
+ });
+
+ $(where).parent().before(clone);
+ }
+ }
+ } else {
+
+ // Else, we remove it from the results tab
+ $("ul#resultul li#k" + key).remove();
+ }
+}
+
+
+ // When a field is checked / unchecked
+ $('input.fieldpick').click(function() {
+ toggleField(this);
+ // (un)check all subfields
+ var ischecked = this.checked;
+ $(this).parent().find("input.subfieldpick").each(function() {
+ this.checked = ischecked;
+ });
+ });
+
+ // When a field or subfield is checked / unchecked
+ $("input.subfieldpick").click(function() {
+ toggleField(this);
+ });
+[% END %]
+[% BLOCK mergesource %]
+
+[% END %]
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/merge.tt
+++ a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/merge.tt
@@ -1,3 +1,4 @@
+[% PROCESS 'merge-record.inc' %]
[% INCLUDE 'doc-head-open.inc' %]
Koha › Cataloging › Merging records
[% INCLUDE 'greybox.inc' %]
@@ -16,152 +17,16 @@ div#result { margin-top: 1em; }
$("ul#ulrecord2").remove();
}
-
$(document).ready(function(){
- // Creating tabs
- $("#tabs").tabs();
-
// Getting marc structure via ajax
tagslib = [];
$.getJSON("/cgi-bin/koha/cataloguing/merge_ajax.pl", {frameworkcode : "[% framework %]" }, function(json) {
- tagslib = json;
+ tagslib = json;
});
-
-
- // Toggle a field / subfield
- function toggleField(pField) {
-
- // Getting the key of the clicked checkbox
- var ckid = $(pField).attr("id");
- var tab = ckid.split('_');
- var source = tab[1]; // From which record the click came from
- var key = tab[2];
- var type = $(pField).attr("class");
-
- // Getting field/subfield
- var field;
- var subfield;
- if (type == "subfieldpick") {
-
- field = $(pField).parent().parent().parent().find("span.field").text();
- subfield = $(pField).parent().find("span.subfield").text();
- } else {
-
- field = $(pField).parent().find("span.field").text();
- }
-
- // If the field has just been checked
- if (pField.checked) {
-
- // We check for repeatability
- var canbeadded = true;
- if (type == "subfieldpick") {
- var repeatable = 1;
- var alreadyexists = 0;
- if (tagslib[field] && tagslib[field][subfield]) {
- repeatable = tagslib[field][subfield].repeatable; // Note : we can't use the dot notation here (tagslib.021) because the key is a number
- // TODO : Checking for subfields
- }
- } else {
- if (tagslib[field]) {
- repeatable = tagslib[field].repeatable;
- alreadyexists = $("#resultul span.field:contains(" + field + ")");
- if (repeatable == 0 && alreadyexists.length != 0) {
- canbeadded = false;
- }
- }
- }
- // If the field is not repeatable, we check if it already exists in the result table
- if (canbeadded == false) {
- alert(_("The field is non-repeatable and already exists in the destination record. Therefore, you cannot add it."));
- pField.checked = 0;
- } else {
-
- // Cloning the field or subfield we picked
- var clone = $(pField).parent().clone();
-
- // Removing the checkboxes from it
- $(clone).find("input.subfieldpick, input.fieldpick").each(function() {
- $(this).remove();
- });
-
-
- // If we are a subfield
- if (type == "subfieldpick") {
- // then we need to find who is our parent field...
- fieldkey = $(pField).parent().parent().parent().attr("id");
-
- // Find where to add the subfield
-
- // First, check if the field is not already in the destination record
- if ($("#resultul li#" + fieldkey).length > 0) {
- // If so, we add our field to it
- $("#resultul li#" + fieldkey + " ul").append(clone);
- } else {
- // If not, we add the subfield to the first matching field
- var where = 0;
- $("#resultul li span.field").each(function() {
- if (where == 0 && $(this).text() == field) {
- where = this;
- }
- });
-
- // If there is no matching field in the destination record
- if (where == 0) {
-
- // TODO:
- // We select the whole field and removing non-selected subfields, instead of...
-
- // Alerting the user
- alert(_("This subfield cannot be added: there is no") + " " + field + " " + _("field in the destination record."));
- pField.checked = false;
-
- } else {
- $(where).nextAll("ul").append(clone);
- }
-
- }
-
-
-
- } else {
- // If we are a field
- var where = 0;
- // Find where to add the field
- $("#resultul li span.field").each(function() {
- if (where == 0 && $(this).text() > field) {
- where = this;
- }
- });
-
- $(where).parent().before(clone);
- }
- }
- } else {
-
- // Else, we remove it from the results tab
- $("ul#resultul li#k" + key).remove();
- }
-}
-
-
- // When a field is checked / unchecked
- $('input.fieldpick').click(function() {
- toggleField(this);
- // (un)check all subfields
- var ischecked = this.checked;
- $(this).parent().find("input.subfieldpick").each(function() {
- this.checked = ischecked;
- });
- });
-
- // When a field or subfield is checked / unchecked
- $("input.subfieldpick").click(function() {
- toggleField(this);
- });
-
+ [% PROCESS mergejs %]
});
+
function changeFramework(fw) {
$("#Frameworks").val(fw);
}
@@ -253,127 +118,10 @@ function changeFramework(fw) {