From c0a1771c3aaf0e7d2b1d3f77352a1c2196af49f1 Mon Sep 17 00:00:00 2001
From: Kyle M Hall <kyle@bywatersolutions.com>
Date: Tue, 3 Dec 2019 15:16:57 -0500
Subject: [PATCH] Bug 24165: Add ability to send any item field in a library
 chosen SIP field
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Some SIP devices need access to item fields that are not sent as item information in the checkin, checkout and item information responses.
It makes sense to allow these fields to be sent in an arbitrary and configurable way, rather than hard code in each special case.

Test Plan:
1) Apply this patch
2) Edit your SIP2 config file, add the following within the login stanza:
   <item_field field="XX" code="<item field 1>" />
   <item_field field="XZ" code="<item fied 2>" />
   where <item field 1> and <item field 2> are item table columns of your choosing
3) Using the sip cli emulator, run checkout, checkin and item information
   messages using that item.
4) Note the values you set for the item columns are sent in the
   corrosponding fields!

Signed-off-by: Jill Kleven <jill.kleven@pueblolibrary.org>
Fixed merge conflict with number of tests (was 5, changed to 7 which is correct)
Signed-off-by: Joonas Kylmälä <joonas.kylmala@helsinki.fi>
---
 C4/SIP/ILS/Item.pm           | 32 ++++++++++++++++++++++++++++++++
 C4/SIP/Sip/MsgType.pm        |  5 +++++
 etc/SIPconfig.xml            |  1 +
 t/db_dependent/SIP/Message.t | 31 ++++++++++++++++++++++++++++++-
 4 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/C4/SIP/ILS/Item.pm b/C4/SIP/ILS/Item.pm
index 705abd70dc..340fc67cc3 100644
--- a/C4/SIP/ILS/Item.pm
+++ b/C4/SIP/ILS/Item.pm
@@ -14,6 +14,7 @@ use Carp;
 use Template;
 
 use C4::SIP::ILS::Transaction;
+use C4::SIP::Sip qw(add_field);
 
 use C4::Debug;
 use C4::Context;
@@ -87,6 +88,8 @@ sub new {
     $self->{'collection_code'} = $item->ccode;
     $self->{  'call_number'  } = $item->itemcallnumber;
 
+    $self->{object} = $item;
+
     my $it = $item->effective_itemtype;
     my $itemtype = Koha::Database->new()->schema()->resultset('Itemtype')->find( $it );
     $self->{sip_media_type} = $itemtype->sip_media_type() if $itemtype;
@@ -387,6 +390,35 @@ sub fill_reserve {
     }
     return ModReserveFill($hold);
 }
+
+=head2 build_additional_item_fields_string
+
+This method builds the part of the sip message for additional item fields
+to send in the item related message responses
+
+=cut
+
+sub build_additional_item_fields_string {
+    my ( $self, $server ) = @_;
+
+    my $string = q{};
+
+    if ( $server->{account}->{item_field} ) {
+        my @fields_to_send =
+          ref $server->{account}->{item_field} eq "ARRAY"
+          ? @{ $server->{account}->{item_field} }
+          : ( $server->{account}->{item_field} );
+
+        foreach my $f ( @fields_to_send ) {
+            my $code = $f->{code};
+            my $value = $self->{object}->$code;
+            $string .= add_field( $f->{field}, $value );
+        }
+    }
+
+    return $string;
+}
+
 1;
 __END__
 
diff --git a/C4/SIP/Sip/MsgType.pm b/C4/SIP/Sip/MsgType.pm
index a61cd7b716..c35c901edf 100644
--- a/C4/SIP/Sip/MsgType.pm
+++ b/C4/SIP/Sip/MsgType.pm
@@ -613,6 +613,8 @@ sub handle_checkout {
         }
     }
 
+    $resp .= $item->build_additional_item_fields_string( $server ) if $item;
+
     if ( $protocol_version >= 2 ) {
 
         # Financials : return irrespective of ok status
@@ -680,6 +682,7 @@ sub handle_checkin {
     if ($item) {
         $resp .= add_field( FID_PERM_LOCN, $item->permanent_location, $server );
         $resp .= maybe_add( FID_TITLE_ID, $item->title_id, $server );
+        $resp .= $item->build_additional_item_fields_string( $server );
     }
 
     if ( $protocol_version >= 2 ) {
@@ -1232,6 +1235,8 @@ sub handle_item_information {
 
         $resp .= maybe_add( FID_SCREEN_MSG, $item->screen_msg, $server );
         $resp .= maybe_add( FID_PRINT_LINE, $item->print_line, $server );
+
+        $resp .= $item->build_additional_item_fields_string( $server );
     }
 
     $self->write_msg( $resp, undef, $server->{account}->{terminator}, $server->{account}->{encoding} );
diff --git a/etc/SIPconfig.xml b/etc/SIPconfig.xml
index 43f53e2160..f140ff253e 100644
--- a/etc/SIPconfig.xml
+++ b/etc/SIPconfig.xml
@@ -63,6 +63,7 @@
           <screen_msg_regex find="Greetings from Koha." replace="Welcome to your library!" />
           <screen_msg_regex find="Invalid patron barcode." replace="Barcode not found, are you sure this is your library card?" />
           <patron_attribute field="XY" code="CODE" />
+          <item_field field="ZY" code="permanent_location" />
           <syspref_overrides>
               <AllFinesNeedOverride>0</AllFinesNeedOverride>
           </syspref_overrides>
diff --git a/t/db_dependent/SIP/Message.t b/t/db_dependent/SIP/Message.t
index e3a81c54cd..3b6eed812d 100755
--- a/t/db_dependent/SIP/Message.t
+++ b/t/db_dependent/SIP/Message.t
@@ -21,7 +21,7 @@
 # along with Koha; if not, see <http://www.gnu.org/licenses>.
 
 use Modern::Perl;
-use Test::More tests => 6;
+use Test::More tests => 7;
 use Test::MockObject;
 use Test::MockModule;
 use Test::Warn;
@@ -167,6 +167,35 @@ subtest 'Lastseen response' => sub {
     $schema->storage->txn_rollback;
 
 };
+
+subtest "Test build_additional_item_fields_string" => sub {
+    my $schema = Koha::Database->new->schema;
+    $schema->storage->txn_begin;
+
+    plan tests => 2;
+
+    my $builder = t::lib::TestBuilder->new();
+
+    my $item = $builder->build( { source => 'Item' } );
+    my $ils_item = C4::SIP::ILS::Item->new( $item->{barcode} );
+
+    my $server = {};
+    $server->{account}->{item_field}->{code} = 'itemnumber';
+    $server->{account}->{item_field}->{field} = 'XY';
+    my $attribute_string = $ils_item->build_additional_item_fields_string( $server );
+    is( $attribute_string, "XY$item->{itemnumber}|", 'Attribute field generated correctly with single param' );
+
+    $server = {};
+    $server->{account}->{item_field}->[0]->{code} = 'itemnumber';
+    $server->{account}->{item_field}->[0]->{field} = 'XY';
+    $server->{account}->{item_field}->[1]->{code} = 'biblionumber';
+    $server->{account}->{item_field}->[1]->{field} = 'YZ';
+    $attribute_string = $ils_item->build_additional_item_fields_string( $server );
+    is( $attribute_string, "XY$item->{itemnumber}|YZ$item->{biblionumber}|", 'Attribute field generated correctly with multiple params' );
+
+    $schema->storage->txn_rollback;
+};
+
 # Here is room for some more subtests
 
 # END of main code
-- 
2.11.0