From 2a69081b2aa8dda6ba676cc1ede65586dd97b006 Mon Sep 17 00:00:00 2001
From: Tomas Cohen Arazi <tomascohen@theke.io>
Date: Mon, 18 Sep 2023 09:35:16 -0300
Subject: [PATCH] [ALTERNATE] Bug 33955: Introduce Koha::MetadataExtractor and
 ->get_normalized_upc

This patch introduces a new pattern for the different ->get_<thing>
methods we've been adding. The aim is that code will look more like:

my $metadata_extractor = Koha::MetadataExtractor->new;

while ( my $biblio = $biblios->next ) {
    my $record = $biblio->record;
    my $schema = $biblio->record_schema;

    $data->{$biblio->id}->{normalized_upc} =
$metadata_extractor->get_normalized_upc( { record => $record, schema =>
$schema } );
    $data->{$biblio->id}->{normalized_ean} =
$metadata_extractor->get_normalized_ean( { record => $record, schema =>
$schema } );
}

The key is that we are actually reusing the MARC::Record, and code for
each schema is organized cleanly so easier to maintain.
---
 Koha/MetadataExtractor.pm              | 109 +++++++++++++++++++++++++
 Koha/MetadataExtractor/MARC/MARC21.pm  |  87 ++++++++++++++++++++
 Koha/MetadataExtractor/MARC/UNIMARC.pm |  86 +++++++++++++++++++
 3 files changed, 282 insertions(+)
 create mode 100644 Koha/MetadataExtractor.pm
 create mode 100644 Koha/MetadataExtractor/MARC/MARC21.pm
 create mode 100644 Koha/MetadataExtractor/MARC/UNIMARC.pm

diff --git a/Koha/MetadataExtractor.pm b/Koha/MetadataExtractor.pm
new file mode 100644
index 00000000000..2aba6b43266
--- /dev/null
+++ b/Koha/MetadataExtractor.pm
@@ -0,0 +1,109 @@
+package Koha::MetadataExtractor;
+
+# Copyright ByWater Solutions 2023
+#
+# 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, see <http://www.gnu.org/licenses>.
+
+=head1 NAME
+
+Koha::MetadataExtractor - Extract specific metadata from MARC::Record objects
+
+=cut
+
+use Modern::Perl;
+
+use Koha::Exceptions;
+use List::MoreUtils qw( any );
+
+=head1 API
+
+=head2 Class methods
+
+=head3 new
+
+    my $extractor = Koha::MetadataExtractor->new;
+
+Constructor for the I<Koha::MetadataExtractor> class.
+
+=cut
+
+sub new {
+    my ($class) = @_;
+    my $self = { extractors => {} };
+
+    return
+        bless $self,
+        $class;
+}
+
+=head2 get_normalized_upc
+
+    my $normalized_upc = $extractor->get_normalized_upc( { record => $record, schema => $schema } );
+
+Returns the normalized UPC for the passed I<$record>.
+
+=cut
+
+sub get_normalized_upc {
+    my ( $self, $params ) = @_;
+
+    Koha::Exceptions::MissingParameter->throw( parameter => 'record' )
+        unless $params->{record};
+
+    return $self->get_extractor( { schema => $params->{schema} } )->get_normalized_upc( $params->{record} );
+}
+
+=head2 Internal methods
+
+=head3 get_extractor
+
+    my $extractor = $self->get_extractor( { schema => $schema } );
+
+Returns the cached extractor for the specified I<$schema>.
+
+=cut
+
+sub get_extractor {
+    my ( $self, $params ) = @_;
+
+    my $schema = $params->{schema};
+
+    Koha::Exceptions::MissingParameter->throw( parameter => 'schema' )
+        unless $schema;
+
+    my $valid_schemas = { 'MARC21' => 1, 'UNIMARC' => 1 };
+
+    Koha::Exceptions::WrongParameter->throw( name => 'schema', value => $schema )
+        unless $valid_schemas->{$schema};
+
+    unless ( $self->{extractors}->{$schema} ) {
+        my $extractor_class = "Koha::MetadataExtractor::MARC::$schema";
+        eval "require $extractor_class";
+        $self->{extractors}->{$schema} = $extractor_class->new;
+    }
+
+    return $self->{extractors}->{$schema};
+}
+
+=head1 AUTHOR
+
+Tomas Cohen Arazi, E<lt>tomascohen@theke.ioE<gt>
+
+=cut
+
+1;
+
+__END__
diff --git a/Koha/MetadataExtractor/MARC/MARC21.pm b/Koha/MetadataExtractor/MARC/MARC21.pm
new file mode 100644
index 00000000000..b3522b02782
--- /dev/null
+++ b/Koha/MetadataExtractor/MARC/MARC21.pm
@@ -0,0 +1,87 @@
+package Koha::MetadataExtractor::MARC::MARC21;
+
+# Copyright ByWater Solutions 2023
+#
+# 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, see <http://www.gnu.org/licenses>.
+
+=head1 NAME
+
+Koha::MetadataExtractor - Extract specific metadata from MARC::Record objects
+
+=cut
+
+use Modern::Perl;
+
+use Koha::Exceptions;
+
+use URI::Escape qw( uri_escape_utf8 );
+
+=head1 API
+
+=head2 Class methods
+
+=head3 new
+
+    my $extractor = Koha::MetadataExtractor::MARC::MARC21->new;
+
+Constructor for the I<Koha::MetadataExtractor> class.
+
+=cut
+
+sub new {
+    my ($class) = @_;
+    my $self = {};
+
+    return
+        bless $self,
+        $class;
+}
+
+=head2 get_normalized_upc
+
+    my $normalized_upc = $extractor->get_normalized_upc( $record );
+
+Returns a stringthe COinS (a span) which can be included in a biblio record
+
+=cut
+
+sub get_normalized_upc {
+    my ( $self, $record ) = @_;
+
+    my @fields = $record->field('024');
+    foreach my $field (@fields) {
+
+        my $indicator = $field->indicator(1);
+        my $upc       = $field->subfield('a');
+
+        ( my $normalized_upc ) = $upc =~ /([\d-]*[X]*)/;
+        $normalized_upc =~ s/-//g;
+
+        if ( $normalized_upc && $indicator == 1 ) {
+            return $normalized_upc;
+        }
+    }
+}
+
+=head1 AUTHOR
+
+Tomas Cohen Arazi, E<lt>tomascohen@theke.ioE<gt>
+
+=cut
+
+1;
+
+__END__
diff --git a/Koha/MetadataExtractor/MARC/UNIMARC.pm b/Koha/MetadataExtractor/MARC/UNIMARC.pm
new file mode 100644
index 00000000000..8248e4397b0
--- /dev/null
+++ b/Koha/MetadataExtractor/MARC/UNIMARC.pm
@@ -0,0 +1,86 @@
+package Koha::MetadataExtractor::MARC::UNIMARC;
+
+# Copyright ByWater Solutions 2023
+#
+# 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, see <http://www.gnu.org/licenses>.
+
+=head1 NAME
+
+Koha::MetadataExtractor - Extract specific metadata from MARC::Record objects
+
+=cut
+
+use Modern::Perl;
+
+use Koha::Exceptions;
+
+use URI::Escape qw( uri_escape_utf8 );
+
+=head1 API
+
+=head2 Class methods
+
+=head3 new
+
+    my $extractor = Koha::MetadataExtractor::MARC::UNIMARC->new;
+
+Constructor for the I<Koha::MetadataExtractor::MARC::UNIMARC> class.
+
+=cut
+
+sub new {
+    my ($class) = @_;
+    my $self = {};
+
+    return
+        bless $self,
+        $class;
+}
+
+=head2 get_normalized_upc
+
+    my $normalized_upc = $extractor->get_normalized_upc( $record );
+
+Returns the normalized UPC for the passed I<$record>.
+
+=cut
+
+sub get_normalized_upc {
+    my ( $self, $record ) = @_;
+
+    my @fields = $record->field('072');
+    foreach my $field (@fields) {
+
+        my $upc = $field->subfield('a');
+
+        ( my $normalized_upc ) = $upc =~ /([\d-]*[X]*)/;
+        $normalized_upc =~ s/-//g;
+
+        if ($normalized_upc) {
+            return $normalized_upc;
+        }
+    }
+}
+
+=head1 AUTHOR
+
+Tomas Cohen Arazi, E<lt>tomascohen@theke.ioE<gt>
+
+=cut
+
+1;
+
+__END__
-- 
2.42.0