Bug 32806: Rename ERMHome and ERMMain to Home and Main
[koha-ffzg.git] / Koha / Illrequest.pm
index 74d9b84..723b118 100644 (file)
@@ -19,16 +19,13 @@ package Koha::Illrequest;
 
 use Modern::Perl;
 
-use Clone 'clone';
-use File::Basename qw( basename );
-use Encode qw( encode );
-use Try::Tiny;
+use Clone qw( clone );
+use Try::Tiny qw( catch try );
 use DateTime;
 
 use C4::Letters;
-use C4::Members;
 use Koha::Database;
-use Koha::DateUtils qw/ dt_from_string /;
+use Koha::DateUtils qw( dt_from_string );
 use Koha::Exceptions::Ill;
 use Koha::Illcomments;
 use Koha::Illrequestattributes;
@@ -41,7 +38,7 @@ use Koha::Items;
 use Koha::ItemTypes;
 use Koha::Libraries;
 
-use C4::Circulation qw( CanBookBeIssued AddIssue  );
+use C4::Circulation qw( CanBookBeIssued AddIssue );
 
 use base qw(Koha::Object);
 
@@ -119,6 +116,33 @@ available for request.
 
 =head2 Class methods
 
+=head3 init_processors
+
+    $request->init_processors()
+
+Initialises an empty processors arrayref
+
+=cut
+
+sub init_processors {
+    my ( $self ) = @_;
+
+    $self->{processors} = [];
+}
+
+=head3 push_processor
+
+    $request->push_processors(sub { ...something... });
+
+Pushes a passed processor function into our processors arrayref
+
+=cut
+
+sub push_processor {
+    my ( $self, $processor ) = @_;
+    push @{$self->{processors}}, $processor;
+}
+
 =head3 statusalias
 
     my $statusalias = $request->statusalias;
@@ -374,6 +398,7 @@ sub _backend_capability {
     try {
         $capability = $self->_backend->capabilities($name);
     } catch {
+        warn $_;
         return 0;
     };
     # Try to invoke it
@@ -572,7 +597,8 @@ sub _status_graph_union {
             if ( grep { $prev_action eq $_ } @core_status_ids ) {
                 my @next_actions =
                      @{$status_graph->{$prev_action}->{next_actions}};
-                push @next_actions, $backend_status_key;
+                push @next_actions, $backend_status_key
+                    if (!grep(/^$backend_status_key$/, @next_actions));
                 $status_graph->{$prev_action}->{next_actions}
                     = \@next_actions;
             }
@@ -582,7 +608,8 @@ sub _status_graph_union {
             if ( grep { $next_action eq $_ } @core_status_ids ) {
                 my @prev_actions =
                      @{$status_graph->{$next_action}->{prev_actions}};
-                push @prev_actions, $backend_status_key;
+                push @prev_actions, $backend_status_key
+                    if (!grep(/^$backend_status_key$/, @prev_actions));
                 $status_graph->{$next_action}->{prev_actions}
                     = \@prev_actions;
             }
@@ -713,6 +740,23 @@ sub mark_completed {
     };
 }
 
+=head2 backend_illview
+
+View and manage an ILL request
+
+=cut
+
+sub backend_illview {
+    my ( $self, $params ) = @_;
+
+    my $response = $self->_backend_capability('illview',{
+        request    => $self,
+        other      => $params,
+    });
+    return $self->expandTemplate($response) if $response;
+    return $response;
+}
+
 =head2 backend_migrate
 
 Migrate a request from one backend to another.
@@ -721,7 +765,8 @@ Migrate a request from one backend to another.
 
 sub backend_migrate {
     my ( $self, $params ) = @_;
-
+    # Set the request's backend to be the destination backend
+    $self->load_backend($params->{backend});
     my $response = $self->_backend_capability('migrate',{
             request    => $self,
             other      => $params,
@@ -879,6 +924,28 @@ sub backend_create {
     return $self->expandTemplate($result);
 }
 
+=head3 backend_get_update
+
+    my $update = backend_get_update($request);
+
+    Given a request, returns an update in a prescribed
+    format that can then be passed to update parsers
+
+=cut
+
+sub backend_get_update {
+    my ( $self, $options ) = @_;
+
+    my $response = $self->_backend_capability(
+        'get_supplier_update',
+        {
+            request => $self,
+            %{$options}
+        }
+    );
+    return $response;
+}
+
 =head3 expandTemplate
 
     my $params = $abstract->expandTemplate($params);
@@ -1222,7 +1289,7 @@ sub check_out {
             scalar $target_item->barcode
         );
         if ($params->{duedate} && length $params->{duedate} > 0) {
-            push @issue_args, $params->{duedate};
+            push @issue_args, dt_from_string($params->{duedate});
         }
         # Check if we can check out
         my ( $error, $confirm, $alerts, $messages ) =
@@ -1329,13 +1396,19 @@ sub generic_confirm {
         my $to = $params->{partners};
         if ( defined $to ) {
             $to =~ s/^\x00//;       # Strip leading NULLs
-            $to =~ s/\x00/; /;      # Replace others with '; '
         }
         Koha::Exceptions::Ill::NoTargetEmail->throw(
             "No target email addresses found. Either select at least one partner or check your ILL partner library records.")
           if ( !$to );
+
+        # Take the null delimited string that we receive and create
+        # an array of associated patron objects
+        my @to_patrons = map {
+            Koha::Patrons->find({ borrowernumber => $_ })
+        } split(/\x00/, $to);
+
         # Create the from, replyto and sender headers
-        my $from = $branch->branchemail;
+        my $from = $branch->from_email_address;
         my $replyto = $branch->inbound_ill_address;
         Koha::Exceptions::Ill::NoLibraryEmail->throw(
             "Your library has no usable email address. Please set it.")
@@ -1350,25 +1423,36 @@ sub generic_confirm {
         $letter->{title} = $params->{subject};
         $letter->{content} = $params->{body};
 
-        # Queue the notice
-        my $params = {
-            letter                 => $letter,
-            borrowernumber         => $self->borrowernumber,
-            message_transport_type => 'email',
-            to_address             => $to,
-            from_address           => $from,
-            reply_address          => $replyto
-        };
-
         if ($letter) {
-            my $result = C4::Letters::EnqueueLetter($params);
-            if ( $result ) {
+
+            # Keep track of who received this notice
+            my @queued = ();
+            # Iterate our array of recipient patron objects
+            foreach my $patron(@to_patrons) {
+                # Create the params we pass to the notice
+                my $params = {
+                    letter                 => $letter,
+                    borrowernumber         => $patron->borrowernumber,
+                    message_transport_type => 'email',
+                    to_address             => $patron->email,
+                    from_address           => $from,
+                    reply_address          => $replyto
+                };
+                my $result = C4::Letters::EnqueueLetter($params);
+                if ( $result ) {
+                    push @queued, $patron->email;
+                }
+            }
+
+            # If all notices were queued successfully,
+            # store that
+            if (scalar @queued == scalar @to_patrons) {
                 $self->status("GENREQ")->store;
                 $self->_backend_capability(
                     'set_requested_partners',
                     {
                         request => $self,
-                        to => $to
+                        to => join("; ", @queued)
                     }
                 );
                 return {
@@ -1380,6 +1464,7 @@ sub generic_confirm {
                     next    => 'illview',
                 };
             }
+
         }
         return {
             error   => 1,
@@ -1402,7 +1487,7 @@ Send a specified notice regarding this request to a patron
 =cut
 
 sub send_patron_notice {
-    my ( $self, $notice_code ) = @_;
+    my ( $self, $notice_code, $additional_text ) = @_;
 
     # We need a notice code
     if (!$notice_code) {
@@ -1413,8 +1498,9 @@ sub send_patron_notice {
 
     # Map from the notice code to the messaging preference
     my %message_name = (
-        ILL_PICKUP_READY   => 'Ill_ready',
-        ILL_REQUEST_UNAVAIL => 'Ill_unavailable'
+        ILL_PICKUP_READY    => 'Ill_ready',
+        ILL_REQUEST_UNAVAIL => 'Ill_unavailable',
+        ILL_REQUEST_UPDATE  => 'Ill_update'
     );
 
     # Get the patron's messaging preferences
@@ -1427,7 +1513,7 @@ sub send_patron_notice {
     # Notice should come from the library where the request was placed,
     # not the patrons home library
     my $branch = Koha::Libraries->find($self->branchcode);
-    my $from_address = $branch->branchemail;
+    my $from_address = $branch->from_email_address;
     my $reply_address = $branch->inbound_ill_address;
 
     # Send the notice to the patron via the chosen transport methods
@@ -1436,8 +1522,9 @@ sub send_patron_notice {
     my @fail = ();
     for my $transport (@transports) {
         my $letter = $self->get_notice({
-            notice_code => $notice_code,
-            transport   => $transport
+            notice_code     => $notice_code,
+            transport       => $transport,
+            additional_text => $additional_text
         });
         if ($letter) {
             my $result = C4::Letters::EnqueueLetter({
@@ -1558,7 +1645,8 @@ sub get_notice {
     );
     my $metahash = $self->metadata;
     my @metaarray = ();
-    while (my($key, $value) = each %{$metahash}) {
+    foreach my $key (sort { lc $a cmp lc $b } keys %{$metahash}) {
+        my $value = $metahash->{$key};
         push @metaarray, "- $key: $value" if $value;
     }
     my $metastring = join("\n", @metaarray);
@@ -1577,13 +1665,50 @@ sub get_notice {
         substitute  => {
             ill_bib_title      => $title ? $title->value : '',
             ill_bib_author     => $author ? $author->value : '',
-            ill_full_metadata  => $metastring
+            ill_full_metadata  => $metastring,
+            additional_text    => $params->{additional_text}
         }
     );
 
     return $letter;
 }
 
+
+=head3 attach_processors
+
+Receive a Koha::Illrequest::SupplierUpdate and attach
+any processors we have for it
+
+=cut
+
+sub attach_processors {
+    my ( $self, $update ) = @_;
+
+    foreach my $processor(@{$self->{processors}}) {
+        if (
+            $processor->{target_source_type} eq $update->{source_type} &&
+            $processor->{target_source_name} eq $update->{source_name}
+        ) {
+            $update->attach_processor($processor);
+        }
+    }
+}
+
+=head3 append_to_note
+
+    append_to_note("Some text");
+
+Append some text to the staff note
+
+=cut
+
+sub append_to_note {
+    my ($self, $text) = @_;
+    my $current = $self->notesstaff;
+    $text = ($current && length $current > 0) ? "$current\n\n$text" : $text;
+    $self->notesstaff($text)->store;
+}
+
 =head3 id_prefix
 
     my $prefix = $record->id_prefix;
@@ -1633,8 +1758,29 @@ possibly records the fact that something happened
 sub store {
     my ( $self, $attrs ) = @_;
 
+    my %updated_columns = $self->_result->get_dirty_columns;
+
+    my @holds;
+    if( $self->in_storage and defined $updated_columns{'borrowernumber'} and
+        Koha::Patrons->find( $updated_columns{'borrowernumber'} ) )
+    {
+        # borrowernumber has changed
+        my $old_illreq = $self->get_from_storage;
+        @holds = Koha::Holds->search( {
+            borrowernumber => $old_illreq->borrowernumber,
+            biblionumber   => $self->biblio_id,
+        } )->as_list if $old_illreq;
+    }
+
     my $ret = $self->SUPER::store;
 
+    if ( scalar @holds ) {
+        # move holds to the changed borrowernumber
+        foreach my $hold ( @holds ) {
+            $hold->borrowernumber( $updated_columns{'borrowernumber'} )->store;
+        }
+    }
+
     $attrs->{log_origin} = 'core';
 
     if ($ret && defined $attrs) {