1 package Koha::Illrequest;
3 # Copyright PTFS Europe 2016
5 # This file is part of Koha.
7 # Koha is free software; you can redistribute it and/or modify it under the
8 # terms of the GNU General Public License as published by the Free Software
9 # Foundation; either version 3 of the License, or (at your option) any later
12 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 # You should have received a copy of the GNU General Public License along with
18 # Koha; if not, write to the Free Software Foundation, Inc., 51 Franklin
19 # Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 use File::Basename qw( basename );
25 use Encode qw( encode );
32 use Koha::Exceptions::Ill;
33 use Koha::Illcomments;
34 use Koha::Illrequestattributes;
35 use Koha::AuthorisedValue;
36 use Koha::Illrequest::Logger;
38 use Koha::AuthorisedValues;
40 use base qw(Koha::Object);
44 Koha::Illrequest - Koha Illrequest Object class
48 An ILLRequest consists of two parts; the Illrequest Koha::Object, and a series
49 of related Illrequestattributes.
51 The former encapsulates the basic necessary information that any ILL requires
52 to be usable in Koha. The latter is a set of additional properties used by
55 The former subsumes the legacy "Status" object. The latter remains
56 encapsulated in the "Record" object.
60 - Anything invoking the ->status method; annotated with:
61 + # Old use of ->status !
65 =head2 Backend API Response Principles
67 All methods should return a hashref in the following format:
73 This should be set to 1 if an error was encountered.
77 The status should be a string from the list of statuses detailed below.
81 The message is a free text field that can be passed on to the end user.
85 The value returned by the method.
89 =head2 Interface Status Messages
93 =item * branch_address_incomplete
95 An interface request has determined branch address details are incomplete.
97 =item * cancel_success
99 The interface's cancel_request method was successful in cancelling the
100 Illrequest using the API.
104 The interface's cancel_request method failed to cancel the Illrequest using
109 The interface's request method returned saying that the desired item is not
110 available for request.
118 my $statusalias = $request->statusalias;
120 Returns a request's status alias, as a Koha::AuthorisedValue instance
121 or implicit undef. This is distinct from status_alias, which only returns
122 the value in the status_alias column, this method returns the entire
123 AuthorisedValue object
129 return unless $self->status_alias;
130 # We can't know which result is the right one if there are multiple
131 # ILLSTATUS authorised values with the same authorised_value column value
132 # so we just use the first
133 return Koha::AuthorisedValues->search({
134 branchcode => $self->branchcode,
135 category => 'ILLSTATUS',
136 authorised_value => $self->SUPER::status_alias
140 =head3 illrequestattributes
144 sub illrequestattributes {
146 return Koha::Illrequestattributes->_new_from_dbic(
147 scalar $self->_result->illrequestattributes
157 return Koha::Illcomments->_new_from_dbic(
158 scalar $self->_result->illcomments
168 my $logger = Koha::Illrequest::Logger->new;
169 return $logger->get_request_logs($self);
178 return Koha::Patron->_new_from_dbic(
179 scalar $self->_result->borrowernumber
185 $Illrequest->status_alias(143);
187 Overloaded getter/setter for status_alias,
188 that only returns authorised values from the
189 correct category and records the fact that the status has changed
194 my ($self, $new_status_alias) = @_;
196 my $current_status_alias = $self->SUPER::status_alias;
198 if ($new_status_alias) {
199 # Keep a record of the previous status before we change it,
201 $self->{previous_status} = $current_status_alias ?
202 $current_status_alias :
203 scalar $self->status;
204 # This is hackery to enable us to undefine
205 # status_alias, since we need to have an overloaded
206 # status_alias method to get us around the problem described
208 # https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=20581#c156
209 # We need a way of accepting implied undef, so we can nullify
210 # the status_alias column, when called from $self->status
211 my $val = $new_status_alias eq "-1" ? undef : $new_status_alias;
212 my $ret = $self->SUPER::status_alias($val);
213 my $val_to_log = $val ? $new_status_alias : scalar $self->status;
215 my $logger = Koha::Illrequest::Logger->new;
216 $logger->log_status_change({
221 delete $self->{previous_status};
225 # We can't know which result is the right one if there are multiple
226 # ILLSTATUS authorised values with the same authorised_value column value
227 # so we just use the first
228 my $alias = Koha::AuthorisedValues->search({
229 branchcode => $self->branchcode,
230 category => 'ILLSTATUS',
231 authorised_value => $self->SUPER::status_alias
234 return $alias->authorised_value;
242 $Illrequest->status('CANREQ');
244 Overloaded getter/setter for request status,
245 also nullifies status_alias and records the fact that the status has changed
250 my ( $self, $new_status) = @_;
252 my $current_status = $self->SUPER::status;
253 my $current_status_alias = $self->SUPER::status_alias;
256 # Keep a record of the previous status before we change it,
258 $self->{previous_status} = $current_status_alias ?
259 $current_status_alias :
261 my $ret = $self->SUPER::status($new_status)->store;
262 if ($current_status_alias) {
263 # This is hackery to enable us to undefine
264 # status_alias, since we need to have an overloaded
265 # status_alias method to get us around the problem described
267 # https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=20581#c156
268 # We need a way of passing implied undef to nullify status_alias
269 # so we pass -1, which is special cased in the overloaded setter
270 $self->status_alias("-1");
272 my $logger = Koha::Illrequest::Logger->new;
273 $logger->log_status_change({
278 delete $self->{previous_status};
281 return $current_status;
287 Require "Base.pm" from the relevant ILL backend.
292 my ( $self, $backend_id ) = @_;
294 my @raw = qw/Koha Illbackends/; # Base Path
296 my $backend_name = $backend_id || $self->backend;
298 unless ( defined $backend_name && $backend_name ne '' ) {
299 Koha::Exceptions::Ill::InvalidBackendId->throw(
300 "An invalid backend ID was requested ('')");
303 my $location = join "/", @raw, $backend_name, "Base.pm"; # File to load
304 my $backend_class = join "::", @raw, $backend_name, "Base"; # Package name
306 $self->{_my_backend} = $backend_class->new({
307 config => $self->_config,
308 logger => Koha::Illrequest::Logger->new
316 my $backend = $abstract->_backend($new_backend);
317 my $backend = $abstract->_backend;
319 Getter/Setter for our API object.
324 my ( $self, $backend ) = @_;
325 $self->{_my_backend} = $backend if ( $backend );
326 # Dynamically load our backend object, as late as possible.
327 $self->load_backend unless ( $self->{_my_backend} );
328 return $self->{_my_backend};
331 =head3 _backend_capability
333 my $backend_capability_result = $self->_backend_capability($name, $args);
335 This is a helper method to invoke optional capabilities in the backend. If
336 the capability named by $name is not supported, return 0, else invoke it,
337 passing $args along with the invocation, and return its return value.
339 NOTE: this module suffers from a confusion in termninology:
341 in _backend_capability, the notion of capability refers to an optional feature
342 that is implemented in core, but might not be supported by a given backend.
344 in capabilities & custom_capability, capability refers to entries in the
345 status_graph (after union between backend and core).
347 The easiest way to fix this would be to fix the terminology in
348 capabilities & custom_capability and their callers.
352 sub _backend_capability {
353 my ( $self, $name, $args ) = @_;
356 $capability = $self->_backend->capabilities($name);
361 return &{$capability}($args);
369 my $config = $abstract->_config($config);
370 my $config = $abstract->_config;
372 Getter/Setter for our config object.
377 my ( $self, $config ) = @_;
378 $self->{_my_config} = $config if ( $config );
379 # Load our config object, as late as possible.
380 unless ( $self->{_my_config} ) {
381 $self->{_my_config} = Koha::Illrequest::Config->new;
383 return $self->{_my_config};
392 return $self->_backend->metadata($self);
395 =head3 _core_status_graph
397 my $core_status_graph = $illrequest->_core_status_graph;
399 Returns ILL module's default status graph. A status graph defines the list of
400 available actions at any stage in the ILL workflow. This is for instance used
401 by the perl script & template to generate the correct buttons to display to
402 the end user at any given point.
406 sub _core_status_graph {
410 prev_actions => [ ], # Actions containing buttons
411 # leading to this status
412 id => 'NEW', # ID of this status
413 name => 'New request', # UI name of this status
414 ui_method_name => 'New request', # UI name of method leading
416 method => 'create', # method to this status
417 next_actions => [ 'REQ', 'GENREQ', 'KILL' ], # buttons to add to all
418 # requests with this status
419 ui_method_icon => 'fa-plus', # UI Style class
422 prev_actions => [ 'NEW', 'REQREV', 'QUEUED', 'CANCREQ' ],
425 ui_method_name => 'Confirm request',
427 next_actions => [ 'REQREV', 'COMP' ],
428 ui_method_icon => 'fa-check',
431 prev_actions => [ 'NEW', 'REQREV' ],
433 name => 'Requested from partners',
434 ui_method_name => 'Place request with partners',
435 method => 'generic_confirm',
436 next_actions => [ 'COMP' ],
437 ui_method_icon => 'fa-send-o',
440 prev_actions => [ 'REQ' ],
442 name => 'Request reverted',
443 ui_method_name => 'Revert Request',
445 next_actions => [ 'REQ', 'GENREQ', 'KILL' ],
446 ui_method_icon => 'fa-times',
451 name => 'Queued request',
454 next_actions => [ 'REQ', 'KILL' ],
458 prev_actions => [ 'NEW' ],
460 name => 'Cancellation requested',
463 next_actions => [ 'KILL', 'REQ' ],
467 prev_actions => [ 'REQ' ],
470 ui_method_name => 'Mark completed',
471 method => 'mark_completed',
473 ui_method_icon => 'fa-check',
476 prev_actions => [ 'QUEUED', 'REQREV', 'NEW', 'CANCREQ' ],
479 ui_method_name => 'Delete request',
482 ui_method_icon => 'fa-trash',
487 =head3 _core_status_graph
489 my $status_graph = $illrequest->_core_status_graph($origin, $new_graph);
491 Return a new status_graph, the result of merging $origin & new_graph. This is
492 operation is a union over the sets defied by the two graphs.
494 Each entry in $new_graph is added to $origin. We do not provide a syntax for
495 'subtraction' of entries from $origin.
497 Whilst it is not intended that this works, you can override entries in $origin
498 with entries with the same key in $new_graph. This can lead to problematic
499 behaviour when $new_graph adds an entry, which modifies a dependent entry in
500 $origin, only for the entry in $origin to be replaced later with a new entry
503 NOTE: this procedure does not "re-link" entries in $origin or $new_graph,
504 i.e. each of the graphs need to be correct at the outset of the operation.
508 sub _status_graph_union {
509 my ( $self, $core_status_graph, $backend_status_graph ) = @_;
510 # Create new status graph with:
511 # - all core_status_graph
512 # - for-each each backend_status_graph
513 # + add to new status graph
514 # + for each core prev_action:
515 # * locate core_status
516 # * update next_actions with additional next action.
517 # + for each core next_action:
518 # * locate core_status
519 # * update prev_actions with additional prev action
521 my @core_status_ids = keys %{$core_status_graph};
522 my $status_graph = clone($core_status_graph);
524 foreach my $backend_status_key ( keys %{$backend_status_graph} ) {
525 my $backend_status = $backend_status_graph->{$backend_status_key};
526 # Add to new status graph
527 $status_graph->{$backend_status_key} = $backend_status;
528 # Update all core methods' next_actions.
529 foreach my $prev_action ( @{$backend_status->{prev_actions}} ) {
530 if ( grep $prev_action, @core_status_ids ) {
532 @{$status_graph->{$prev_action}->{next_actions}};
533 push @next_actions, $backend_status_key;
534 $status_graph->{$prev_action}->{next_actions}
538 # Update all core methods' prev_actions
539 foreach my $next_action ( @{$backend_status->{next_actions}} ) {
540 if ( grep $next_action, @core_status_ids ) {
542 @{$status_graph->{$next_action}->{prev_actions}};
543 push @prev_actions, $backend_status_key;
544 $status_graph->{$next_action}->{prev_actions}
550 return $status_graph;
557 my $capabilities = $illrequest->capabilities;
559 Return a hashref mapping methods to operation names supported by the queried
562 Example return value:
564 { create => "Create Request", confirm => "Progress Request" }
566 NOTE: this module suffers from a confusion in termninology:
568 in _backend_capability, the notion of capability refers to an optional feature
569 that is implemented in core, but might not be supported by a given backend.
571 in capabilities & custom_capability, capability refers to entries in the
572 status_graph (after union between backend and core).
574 The easiest way to fix this would be to fix the terminology in
575 capabilities & custom_capability and their callers.
580 my ( $self, $status ) = @_;
581 # Generate up to date status_graph
582 my $status_graph = $self->_status_graph_union(
583 $self->_core_status_graph,
584 $self->_backend->status_graph({
589 # Extract available actions from graph.
590 return $status_graph->{$status} if $status;
591 # Or return entire graph.
592 return $status_graph;
595 =head3 custom_capability
597 Return the result of invoking $CANDIDATE on this request's backend with
598 $PARAMS, or 0 if $CANDIDATE is an unknown method on backend.
600 NOTE: this module suffers from a confusion in termninology:
602 in _backend_capability, the notion of capability refers to an optional feature
603 that is implemented in core, but might not be supported by a given backend.
605 in capabilities & custom_capability, capability refers to entries in the
606 status_graph (after union between backend and core).
608 The easiest way to fix this would be to fix the terminology in
609 capabilities & custom_capability and their callers.
613 sub custom_capability {
614 my ( $self, $candidate, $params ) = @_;
615 foreach my $capability ( values %{$self->capabilities} ) {
616 if ( $candidate eq $capability->{method} ) {
618 $self->_backend->$candidate({
622 return $self->expandTemplate($response);
628 =head3 available_backends
630 Return a list of available backends.
634 sub available_backends {
635 my ( $self, $reduced ) = @_;
636 my $backends = $self->_config->available_backends($reduced);
640 =head3 available_actions
642 Return a list of available actions.
646 sub available_actions {
648 my $current_action = $self->capabilities($self->status);
649 my @available_actions = map { $self->capabilities($_) }
650 @{$current_action->{next_actions}};
651 return \@available_actions;
654 =head3 mark_completed
656 Mark a request as completed (status = COMP).
662 $self->status('COMP')->store;
663 $self->completed(DateTime->now)->store;
668 method => 'mark_completed',
674 =head2 backend_migrate
676 Migrate a request from one backend to another.
680 sub backend_migrate {
681 my ( $self, $params ) = @_;
683 my $response = $self->_backend_capability('migrate',{
687 return $self->expandTemplate($response) if $response;
691 =head2 backend_confirm
693 Confirm a request. The backend handles setting of mandatory fields in the commit stage:
699 =item * accessurl, cost (if available).
705 sub backend_confirm {
706 my ( $self, $params ) = @_;
708 my $response = $self->_backend->confirm({
712 return $self->expandTemplate($response);
715 =head3 backend_update_status
719 sub backend_update_status {
720 my ( $self, $params ) = @_;
721 return $self->expandTemplate($self->_backend->update_status($params));
724 =head3 backend_cancel
726 my $ILLResponse = $illRequest->backend_cancel;
728 The standard interface method allowing for request cancellation.
733 my ( $self, $params ) = @_;
735 my $result = $self->_backend->cancel({
740 return $self->expandTemplate($result);
745 my $renew_response = $illRequest->backend_renew;
747 The standard interface method allowing for request renewal queries.
753 return $self->expandTemplate(
754 $self->_backend->renew({
760 =head3 backend_create
762 my $create_response = $abstractILL->backend_create($params);
764 Return an array of Record objects created by querying our backend with
767 In the context of the other ILL methods, this is a special method: we only
768 pass it $params, as it does not yet have any other data associated with it.
773 my ( $self, $params ) = @_;
775 # Establish whether we need to do a generic copyright clearance.
776 if ($params->{opac}) {
777 if ( ( !$params->{stage} || $params->{stage} eq 'init' )
778 && C4::Context->preference("ILLModuleCopyrightClearance") ) {
784 stage => 'copyrightclearance',
786 backend => $self->_backend->name
789 } elsif ( defined $params->{stage}
790 && $params->{stage} eq 'copyrightclearance' ) {
791 $params->{stage} = 'init';
794 # First perform API action, then...
799 my $result = $self->_backend->create($args);
801 # ... simple case: we're not at 'commit' stage.
802 my $stage = $result->{stage};
803 return $self->expandTemplate($result)
804 unless ( 'commit' eq $stage );
806 # ... complex case: commit!
808 # Do we still have space for an ILL or should we queue?
809 my $permitted = $self->check_limits(
810 { patron => $self->patron }, { librarycode => $self->branchcode }
813 # Now augment our committed request.
815 $result->{permitted} = $permitted; # Queue request?
819 # ...Updating status!
820 $self->status('QUEUED')->store unless ( $permitted );
822 return $self->expandTemplate($result);
825 =head3 expandTemplate
827 my $params = $abstract->expandTemplate($params);
829 Return a version of $PARAMS augmented with our required template path.
834 my ( $self, $params ) = @_;
835 my $backend = $self->_backend->name;
836 # Generate path to file to load
837 my $backend_dir = $self->_config->backend_dir;
838 my $backend_tmpl = join "/", $backend_dir, $backend;
839 my $intra_tmpl = join "/", $backend_tmpl, "intra-includes",
840 $params->{method} . ".inc";
841 my $opac_tmpl = join "/", $backend_tmpl, "opac-includes",
842 $params->{method} . ".inc";
844 $params->{template} = $intra_tmpl;
845 $params->{opac_template} = $opac_tmpl;
849 #### Abstract Imports
853 my $limit_rules = $abstract->getLimits( {
854 type => 'brw_cat' | 'branch',
858 Return the ILL limit rules for the supplied combination of type / value.
860 As the config may have no rules for this particular type / value combination,
861 or for the default, we must define fall-back values here.
866 my ( $self, $params ) = @_;
867 my $limits = $self->_config->getLimitRules($params->{type});
869 if ( defined $params->{value}
870 && defined $limits->{$params->{value}} ) {
871 return $limits->{$params->{value}};
874 return $limits->{default} || { count => -1, method => 'active' };
880 my $prefix = $abstract->getPrefix( {
881 branch => $branch_code
884 Return the ILL prefix as defined by our $params: either per borrower category,
885 per branch or the default.
890 my ( $self, $params ) = @_;
891 my $brn_prefixes = $self->_config->getPrefixes();
892 return $brn_prefixes->{$params->{branch}} || ""; # "the empty prefix"
897 my $type = $abstract->get_type();
899 Return a string representing the material type of this request or undef
905 my $attr = $self->illrequestattributes->find({ type => 'type'});
910 #### Illrequests Imports
914 my $ok = $illRequests->check_limits( {
915 borrower => $borrower,
916 branchcode => 'branchcode' | undef,
919 Given $PARAMS, a hashref containing a $borrower object and a $branchcode,
920 see whether we are still able to place ILLs.
922 LimitRules are derived from koha-conf.xml:
923 + default limit counts, and counting method
924 + branch specific limit counts & counting method
925 + borrower category specific limit counts & counting method
926 + err on the side of caution: a counting fail will cause fail, even if
927 the other counts passes.
932 my ( $self, $params ) = @_;
933 my $patron = $params->{patron};
934 my $branchcode = $params->{librarycode} || $patron->branchcode;
936 # Establish maximum number of allowed requests
937 my ( $branch_rules, $brw_rules ) = (
944 value => $patron->categorycode,
947 my ( $branch_limit, $brw_limit )
948 = ( $branch_rules->{count}, $brw_rules->{count} );
949 # Establish currently existing requests
950 my ( $branch_count, $brw_count ) = (
951 $self->_limit_counter(
952 $branch_rules->{method}, { branchcode => $branchcode }
954 $self->_limit_counter(
955 $brw_rules->{method}, { borrowernumber => $patron->borrowernumber }
960 # A limit of -1 means no limit exists.
961 # We return blocked if either branch limit or brw limit is reached.
962 if ( ( $branch_limit != -1 && $branch_limit <= $branch_count )
963 || ( $brw_limit != -1 && $brw_limit <= $brw_count ) ) {
971 my ( $self, $method, $target ) = @_;
973 # Establish parameters of counts
975 if ($method && $method eq 'annual') {
976 $resultset = Koha::Illrequests->search({
979 \"YEAR(placed) = YEAR(NOW())"
982 } else { # assume 'active'
983 # XXX: This status list is ugly. There should be a method in config
985 my $where = { status => { -not_in => [ 'QUEUED', 'COMP' ] } };
986 $resultset = Koha::Illrequests->search({ %{$target}, %{$where} });
990 return $resultset->count;
993 =head3 requires_moderation
995 my $status = $illRequest->requires_moderation;
997 Return the name of the status if moderation by staff is required; or 0
1002 sub requires_moderation {
1004 my $require_moderation = {
1005 'CANCREQ' => 'CANCREQ',
1007 return $require_moderation->{$self->status};
1010 =head3 generic_confirm
1012 my $stage_summary = $illRequest->generic_confirm;
1014 Handle the generic_confirm extended method. The first stage involves creating
1015 a template email for the end user to edit in the browser. The second stage
1016 attempts to submit the email.
1020 sub generic_confirm {
1021 my ( $self, $params ) = @_;
1022 my $branch = Koha::Libraries->find($params->{current_branchcode})
1023 || die "Invalid current branchcode. Are you logged in as the database user?";
1024 if ( !$params->{stage}|| $params->{stage} eq 'init' ) {
1025 my $draft->{subject} = "ILL Request";
1026 $draft->{body} = <<EOF;
1029 We would like to request an interlibrary loan for a title matching the
1030 following description:
1034 my $details = $self->metadata;
1035 while (my ($title, $value) = each %{$details}) {
1036 $draft->{body} .= " - " . $title . ": " . $value . "\n"
1039 $draft->{body} .= <<EOF;
1041 Please let us know if you are able to supply this to us.
1047 my @address = map { $branch->$_ }
1048 qw/ branchname branchaddress1 branchaddress2 branchaddress3
1049 branchzip branchcity branchstate branchcountry branchphone
1052 foreach my $line ( @address ) {
1053 $address .= $line . "\n" if $line;
1056 $draft->{body} .= $address;
1058 my $partners = Koha::Patrons->search({
1059 categorycode => $self->_config->partner_code
1065 method => 'generic_confirm',
1069 partners => $partners,
1073 } elsif ( 'draft' eq $params->{stage} ) {
1074 # Create the to header
1075 my $to = $params->{partners};
1076 if ( defined $to ) {
1077 $to =~ s/^\x00//; # Strip leading NULLs
1078 $to =~ s/\x00/; /; # Replace others with '; '
1080 Koha::Exceptions::Ill::NoTargetEmail->throw(
1081 "No target email addresses found. Either select at least one partner or check your ILL partner library records.")
1083 # Create the from, replyto and sender headers
1084 my $from = $branch->branchemail;
1085 my $replyto = $branch->branchreplyto || $from;
1086 Koha::Exceptions::Ill::NoLibraryEmail->throw(
1087 "Your library has no usable email address. Please set it.")
1091 my $message = Koha::Email->new;
1092 my %mail = $message->create_message_headers(
1096 replyto => $replyto,
1097 subject => Encode::encode( "utf8", $params->{subject} ),
1098 message => Encode::encode( "utf8", $params->{body} ),
1099 contenttype => 'text/plain',
1103 my $result = sendmail(%mail);
1105 $self->status("GENREQ")->store;
1110 method => 'generic_confirm',
1117 status => 'email_failed',
1118 message => $Mail::Sendmail::error,
1119 method => 'generic_confirm',
1124 die "Unknown stage, should not have happened."
1130 my $prefix = $record->id_prefix;
1132 Return the prefix appropriate for the current Illrequest as derived from the
1133 borrower and branch associated with this request's Status, and the config
1140 my $prefix = $self->getPrefix( {
1141 branch => $self->branchcode,
1143 $prefix .= "-" if ( $prefix );
1149 my $params = $illRequest->_censor($params);
1151 Return $params, modified to reflect our censorship requirements.
1156 my ( $self, $params ) = @_;
1157 my $censorship = $self->_config->censorship;
1158 $params->{censor_notes_staff} = $censorship->{censor_notes_staff}
1159 if ( $params->{opac} );
1160 $params->{display_reply_date} = ( $censorship->{censor_reply_date} ) ? 0 : 1;
1169 Overloaded I<store> method that, in addition to performing the 'store',
1170 possibly records the fact that something happened
1175 my ( $self, $attrs ) = @_;
1177 my $ret = $self->SUPER::store;
1179 $attrs->{log_origin} = 'core';
1181 if ($ret && defined $attrs) {
1182 my $logger = Koha::Illrequest::Logger->new;
1183 $logger->log_maybe({
1194 $json = $illrequest->TO_JSON
1196 Overloaded I<TO_JSON> method that takes care of inserting calculated values
1197 into the unblessed representation of the object.
1199 TODO: This method does nothing and is not called anywhere. However, bug 74325
1200 touches it, so keeping this for now until both this and bug 74325 are merged,
1201 at which point we can sort it out and remove it completely
1206 my ( $self, $embed ) = @_;
1208 my $object = $self->SUPER::TO_JSON();
1213 =head2 Internal methods
1220 return 'Illrequest';
1225 Alex Sassmannshausen <alex.sassmannshausen@ptfs-europe.com>