Bug 7317: Rewrite atomicupdate file
[koha.git] / Koha / Illrequest.pm
blob2b34b8893861843a42d2fafb871efad69649b4a3
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
10 # version.
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
15 # details.
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.
21 # use Modern::Perl;
23 use Clone 'clone';
24 use File::Basename qw/basename/;
25 use Koha::Database;
26 use Koha::Email;
27 use Koha::Illrequest;
28 use Koha::Illrequestattributes;
29 use Koha::Patron;
30 use Mail::Sendmail;
31 use Try::Tiny;
33 use base qw(Koha::Object);
35 =head1 NAME
37 Koha::Illrequest - Koha Illrequest Object class
39 =head1 (Re)Design
41 An ILLRequest consists of two parts; the Illrequest Koha::Object, and a series
42 of related Illrequestattributes.
44 The former encapsulates the basic necessary information that any ILL requires
45 to be usable in Koha. The latter is a set of additional properties used by
46 one of the backends.
48 The former subsumes the legacy "Status" object. The latter remains
49 encapsulated in the "Record" object.
51 TODO:
53 - Anything invoking the ->status method; annotated with:
54 + # Old use of ->status !
56 =head1 API
58 =head2 Backend API Response Principles
60 All methods should return a hashref in the following format:
62 =item * error
64 This should be set to 1 if an error was encountered.
66 =item * status
68 The status should be a string from the list of statuses detailed below.
70 =item * message
72 The message is a free text field that can be passed on to the end user.
74 =item * value
76 The value returned by the method.
78 =over
80 =head2 Interface Status Messages
82 =over
84 =item * branch_address_incomplete
86 An interface request has determined branch address details are incomplete.
88 =item * cancel_success
90 The interface's cancel_request method was successful in cancelling the
91 Illrequest using the API.
93 =item * cancel_fail
95 The interface's cancel_request method failed to cancel the Illrequest using
96 the API.
98 =item * unavailable
100 The interface's request method returned saying that the desired item is not
101 available for request.
103 =head2 Class methods
105 =cut
107 sub illrequestattributes {
108 my ( $self ) = @_;
109 return Koha::Illrequestattributes->_new_from_dbic(
110 scalar $self->_result->illrequestattributes
114 sub patron {
115 my ( $self ) = @_;
116 return Koha::Patron->_new_from_dbic(
117 scalar $self->_result->borrowernumber
121 sub load_backend {
122 my ( $self, $backend_id ) = @_;
124 my @raw = qw/Koha Illbackends/; # Base Path
126 my $backend_name = $backend_id || $self->backend;
127 $location = join "/", @raw, $backend_name, "Base.pm"; # File to load
128 $backend_class = join "::", @raw, $backend_name, "Base"; # Package name
129 require $location;
130 $self->{_my_backend} = $backend_class->new({ config => $self->_config });
131 return $self;
134 =head3 _backend
136 my $backend = $abstract->_backend($new_backend);
137 my $backend = $abstract->_backend;
139 Getter/Setter for our API object.
141 =cut
143 sub _backend {
144 my ( $self, $backend ) = @_;
145 $self->{_my_backend} = $backend if ( $backend );
146 # Dynamically load our backend object, as late as possible.
147 $self->load_backend unless ( $self->{_my_backend} );
148 return $self->{_my_backend};
151 =head3 _backend_capability
153 my $backend_capability_result = $self->_backend_capability($name, $args);
155 This is a helper method to invoke optional capabilities in the backend. If
156 the capability named by $name is not supported, return 0, else invoke it,
157 passing $args along with the invocation, and return its return value.
159 NOTE: this module suffers from a confusion in termninology:
161 in _backend_capability, the notion of capability refers to an optional feature
162 that is implemented in core, but might not be supported by a given backend.
164 in capabilities & custom_capability, capability refers to entries in the
165 status_graph (after union between backend and core).
167 The easiest way to fix this would be to fix the terminology in
168 capabilities & custom_capability and their callers.
170 =cut
172 sub _backend_capability {
173 my ( $self, $name, $args ) = @_;
174 my $capability = 0;
175 try {
176 $capability = $self->_backend->capabilities($name);
177 } catch {
178 return 0;
180 if ( $capability ) {
181 return &{$capability}($args);
182 } else {
183 return 0;
187 =head3 _config
189 my $config = $abstract->_config($config);
190 my $config = $abstract->_config;
192 Getter/Setter for our config object.
194 =cut
196 sub _config {
197 my ( $self, $config ) = @_;
198 $self->{_my_config} = $config if ( $config );
199 # Load our config object, as late as possible.
200 unless ( $self->{_my_config} ) {
201 $self->{_my_config} = Koha::Illrequest::Config->new;
203 return $self->{_my_config};
206 =head3 metadata
208 =cut
210 sub metadata {
211 my ( $self ) = @_;
212 return $self->_backend->metadata($self);
215 =head3 _core_status_graph
217 my $core_status_graph = $illrequest->_core_status_graph;
219 Returns ILL module's default status graph. A status graph defines the list of
220 available actions at any stage in the ILL workflow. This is for instance used
221 by the perl script & template to generate the correct buttons to display to
222 the end user at any given point.
224 =cut
226 sub _core_status_graph {
227 my ( $self ) = @_;
228 return {
229 NEW => {
230 prev_actions => [ ], # Actions containing buttons
231 # leading to this status
232 id => 'NEW', # ID of this status
233 name => 'New request', # UI name of this status
234 ui_method_name => 'New request', # UI name of method leading
235 # to this status
236 method => 'create', # method to this status
237 next_actions => [ 'REQ', 'GENREQ', 'KILL' ], # buttons to add to all
238 # requests with this status
239 ui_method_icon => 'fa-plus', # UI Style class
241 REQ => {
242 prev_actions => [ 'NEW', 'REQREV', 'QUEUED', 'CANCREQ' ],
243 id => 'REQ',
244 name => 'Requested',
245 ui_method_name => 'Confirm request',
246 method => 'confirm',
247 next_actions => [ 'REQREV', 'COMP' ],
248 ui_method_icon => 'fa-check',
250 GENREQ => {
251 prev_actions => [ 'NEW', 'REQREV' ],
252 id => 'GENREQ',
253 name => 'Requested from partners',
254 ui_method_name => 'Place request with partners',
255 method => 'generic_confirm',
256 next_actions => [ 'COMP' ],
257 ui_method_icon => 'fa-send-o',
259 REQREV => {
260 prev_actions => [ 'REQ' ],
261 id => 'REQREV',
262 name => 'Request reverted',
263 ui_method_name => 'Revert Request',
264 method => 'cancel',
265 next_actions => [ 'REQ', 'GENREQ', 'KILL' ],
266 ui_method_icon => 'fa-times',
268 QUEUED => {
269 prev_actions => [ ],
270 id => 'QUEUED',
271 name => 'Queued request',
272 ui_method_name => 0,
273 method => 0,
274 next_actions => [ 'REQ', 'KILL' ],
275 ui_method_icon => 0,
277 CANCREQ => {
278 prev_actions => [ 'NEW' ],
279 id => 'CANCREQ',
280 name => 'Cancellation requested',
281 ui_method_name => 0,
282 method => 0,
283 next_actions => [ 'KILL', 'REQ' ],
284 ui_method_icon => 0,
286 COMP => {
287 prev_actions => [ 'REQ' ],
288 id => 'COMP',
289 name => 'Completed',
290 ui_method_name => 'Mark completed',
291 method => 'mark_completed',
292 next_actions => [ ],
293 ui_method_icon => 'fa-check',
295 KILL => {
296 prev_actions => [ 'QUEUED', 'REQREV', 'NEW', 'CANCREQ' ],
297 id => 'KILL',
298 name => 0,
299 ui_method_name => 'Delete request',
300 method => 'delete',
301 next_actions => [ ],
302 ui_method_icon => 'fa-trash',
307 =head3 _core_status_graph
309 my $status_graph = $illrequest->_core_status_graph($origin, $new_graph);
311 Return a new status_graph, the result of merging $origin & new_graph. This is
312 operation is a union over the sets defied by the two graphs.
314 Each entry in $new_graph is added to $origin. We do not provide a syntax for
315 'subtraction' of entries from $origin.
317 Whilst it is not intended that this works, you can override entries in $origin
318 with entries with the same key in $new_graph. This can lead to problematic
319 behaviour when $new_graph adds an entry, which modifies a dependent entry in
320 $origin, only for the entry in $origin to be replaced later with a new entry
321 from $new_graph.
323 NOTE: this procedure does not "re-link" entries in $origin or $new_graph,
324 i.e. each of the graphs need to be correct at the outset of the operation.
326 =cut
328 sub _status_graph_union {
329 my ( $self, $core_status_graph, $backend_status_graph ) = @_;
330 # Create new status graph with:
331 # - all core_status_graph
332 # - for-each each backend_status_graph
333 # + add to new status graph
334 # + for each core prev_action:
335 # * locate core_status
336 # * update next_actions with additional next action.
337 # + for each core next_action:
338 # * locate core_status
339 # * update prev_actions with additional prev action
341 my @core_status_ids = keys %{$core_status_graph};
342 my $status_graph = clone($core_status_graph);
344 foreach my $backend_status_key ( keys %{$backend_status_graph} ) {
345 $backend_status = $backend_status_graph->{$backend_status_key};
346 # Add to new status graph
347 $status_graph->{$backend_status_key} = $backend_status;
348 # Update all core methods' next_actions.
349 foreach my $prev_action ( @{$backend_status->{prev_actions}} ) {
350 if ( grep $prev_action, @core_status_ids ) {
351 my @next_actions =
352 @{$status_graph->{$prev_action}->{next_actions}};
353 push @next_actions, $backend_status_key;
354 $status_graph->{$prev_action}->{next_actions}
355 = \@next_actions;
358 # Update all core methods' prev_actions
359 foreach my $next_action ( @{$backend_status->{next_actions}} ) {
360 if ( grep $next_action, @core_status_ids ) {
361 my @prev_actions =
362 @{$status_graph->{$next_action}->{prev_actions}};
363 push @prev_actions, $backend_status_key;
364 $status_graph->{$next_action}->{prev_actions}
365 = \@prev_actions;
370 return $status_graph;
373 ### Core API methods
375 =head3 capabilities
377 my $capabilities = $illrequest->capabilities;
379 Return a hashref mapping methods to operation names supported by the queried
380 backend.
382 Example return value:
384 { create => "Create Request", confirm => "Progress Request" }
386 NOTE: this module suffers from a confusion in termninology:
388 in _backend_capability, the notion of capability refers to an optional feature
389 that is implemented in core, but might not be supported by a given backend.
391 in capabilities & custom_capability, capability refers to entries in the
392 status_graph (after union between backend and core).
394 The easiest way to fix this would be to fix the terminology in
395 capabilities & custom_capability and their callers.
397 =cut
399 sub capabilities {
400 my ( $self, $status ) = @_;
401 # Generate up to date status_graph
402 my $status_graph = $self->_status_graph_union(
403 $self->_core_status_graph,
404 $self->_backend->status_graph({
405 request => $self,
406 other => {}
409 # Extract available actions from graph.
410 return $status_graph->{$status} if $status;
411 # Or return entire graph.
412 return $status_graph;
415 =head3 custom_capability
417 Return the result of invoking $CANDIDATE on this request's backend with
418 $PARAMS, or 0 if $CANDIDATE is an unknown method on backend.
420 NOTE: this module suffers from a confusion in termninology:
422 in _backend_capability, the notion of capability refers to an optional feature
423 that is implemented in core, but might not be supported by a given backend.
425 in capabilities & custom_capability, capability refers to entries in the
426 status_graph (after union between backend and core).
428 The easiest way to fix this would be to fix the terminology in
429 capabilities & custom_capability and their callers.
431 =cut
433 sub custom_capability {
434 my ( $self, $candidate, $params ) = @_;
435 foreach my $capability ( values %{$self->capabilities} ) {
436 if ( $candidate eq $capability->{method} ) {
437 my $response =
438 $self->_backend->$candidate({
439 request => $self,
440 other => $params,
442 return $self->expandTemplate($response);
445 return 0;
448 sub available_backends {
449 my ( $self ) = @_;
450 my $backend_dir = $self->_config->backend_dir;
451 my @backends = ();
452 @backends = <$backend_dir/*> if ( $backend_dir );
453 @backends = map { basename($_) } @backends;
454 return \@backends;
457 sub available_actions {
458 my ( $self ) = @_;
459 my $current_action = $self->capabilities($self->status);
460 my @available_actions = map { $self->capabilities($_) }
461 @{$current_action->{next_actions}};
462 return \@available_actions;
465 sub mark_completed {
466 my ( $self ) = @_;
467 $self->status('COMP')->store;
468 return {
469 error => 0,
470 status => '',
471 message => '',
472 method => 'mark_completed',
473 stage => 'commit',
474 next => 'illview',
478 sub backend_confirm {
479 my ( $self, $params ) = @_;
481 # The backend handles setting of mandatory fields in the commit stage:
482 # - orderid
483 # - accessurl, cost (if available).
484 my $response = $self->_backend->confirm({
485 request => $self,
486 other => $params,
488 return $self->expandTemplate($response);
491 sub backend_update_status {
492 my ( $self, $params ) = @_;
493 return $self->expandTemplate($self->_backend->update_status($params));
496 =head3 backend_cancel
498 my $ILLResponse = $illRequest->backend_cancel;
500 The standard interface method allowing for request cancellation.
502 =cut
504 sub backend_cancel {
505 my ( $self, $params ) = @_;
507 my $result = $self->_backend->cancel({
508 request => $self,
509 other => $params
512 return $self->expandTemplate($result);
515 =head3 backend_renew
517 my $renew_response = $illRequest->backend_renew;
519 The standard interface method allowing for request renewal queries.
521 =cut
523 sub backend_renew {
524 my ( $self ) = @_;
525 return $self->expandTemplate(
526 $self->_backend->renew({
527 request => $self,
532 =head3 backend_create
534 my $create_response = $abstractILL->backend_create($params);
536 Return an array of Record objects created by querying our backend with
537 a Search query.
539 In the context of the other ILL methods, this is a special method: we only
540 pass it $params, as it does not yet have any other data associated with it.
542 =cut
544 sub backend_create {
545 my ( $self, $params ) = @_;
547 # Establish whether we need to do a generic copyright clearance.
548 if ( ( !$params->{stage} || $params->{stage} eq 'init' )
549 && C4::Context->preference("ILLModuleCopyrightClearance") ) {
550 return {
551 error => 0,
552 status => '',
553 message => '',
554 method => 'create',
555 stage => 'copyrightclearance',
556 value => {
557 backend => $self->_backend->name
560 } elsif ( $params->{stage} eq 'copyrightclearance' ) {
561 $params->{stage} = 'init';
564 # First perform API action, then...
565 my $args = {
566 request => $self,
567 other => $params,
569 my $result = $self->_backend->create($args);
571 # ... simple case: we're not at 'commit' stage.
572 my $stage = $result->{stage};
573 return $self->expandTemplate($result)
574 unless ( 'commit' eq $stage );
576 # ... complex case: commit!
578 # Do we still have space for an ILL or should we queue?
579 my $permitted = $self->check_limits(
580 { patron => $self->patron }, { librarycode => $self->branchcode }
583 # Now augment our committed request.
585 $result->{permitted} = $permitted; # Queue request?
587 # This involves...
589 # ...Updating status!
590 $self->status('QUEUED')->store unless ( $permitted );
592 return $self->expandTemplate($result);
595 =head3 expandTemplate
597 my $params = $abstract->expandTemplate($params);
599 Return a version of $PARAMS augmented with our required template path.
601 =cut
603 sub expandTemplate {
604 my ( $self, $params ) = @_;
605 my $backend = $self->_backend->name;
606 # Generate path to file to load
607 my $backend_dir = $self->_config->backend_dir;
608 my $backend_tmpl = join "/", $backend_dir, $backend;
609 my $intra_tmpl = join "/", $backend_tmpl, "intra-includes",
610 $params->{method} . ".inc";
611 my $opac_tmpl = join "/", $backend_tmpl, "opac-includes",
612 $params->{method} . ".inc";
613 # Set files to load
614 $params->{template} = $intra_tmpl;
615 $params->{opac_template} = $opac_tmpl;
616 return $params;
619 #### Abstract Imports
621 =head3 getLimits
623 my $limit_rules = $abstract->getLimits( {
624 type => 'brw_cat' | 'branch',
625 value => $value
626 } );
628 Return the ILL limit rules for the supplied combination of type / value.
630 As the config may have no rules for this particular type / value combination,
631 or for the default, we must define fall-back values here.
633 =cut
635 sub getLimits {
636 my ( $self, $params ) = @_;
637 my $limits = $self->_config->getLimitRules($params->{type});
639 return $limits->{$params->{value}}
640 || $limits->{default}
641 || { count => -1, method => 'active' };
644 =head3 getPrefix
646 my $prefix = $abstract->getPrefix( {
647 brw_cat => $brw_cat,
648 branch => $branch_code,
649 } );
651 Return the ILL prefix as defined by our $params: either per borrower category,
652 per branch or the default.
654 =cut
656 sub getPrefix {
657 my ( $self, $params ) = @_;
658 my $brn_prefixes = $self->_config->getPrefixes('branch');
659 my $brw_prefixes = $self->_config->getPrefixes('brw_cat');
661 return $brw_prefixes->{$params->{brw_cat}}
662 || $brn_prefixes->{$params->{branch}}
663 || $brw_prefixes->{default}
664 || ""; # "the empty prefix"
667 #### Illrequests Imports
669 =head3 check_limits
671 my $ok = $illRequests->check_limits( {
672 borrower => $borrower,
673 branchcode => 'branchcode' | undef,
674 } );
676 Given $PARAMS, a hashref containing a $borrower object and a $branchcode,
677 see whether we are still able to place ILLs.
679 LimitRules are derived from koha-conf.xml:
680 + default limit counts, and counting method
681 + branch specific limit counts & counting method
682 + borrower category specific limit counts & counting method
683 + err on the side of caution: a counting fail will cause fail, even if
684 the other counts passes.
686 =cut
688 sub check_limits {
689 my ( $self, $params ) = @_;
690 my $patron = $params->{patron};
691 my $branchcode = $params->{librarycode} || $patron->branchcode;
693 # Establish maximum number of allowed requests
694 my ( $branch_rules, $brw_rules ) = (
695 $self->getLimits( {
696 type => 'branch',
697 value => $branchcode
698 } ),
699 $self->getLimits( {
700 type => 'brw_cat',
701 value => $patron->categorycode,
702 } ),
704 my ( $branch_limit, $brw_limit )
705 = ( $branch_rules->{count}, $brw_rules->{count} );
706 # Establish currently existing requests
707 my ( $branch_count, $brw_count ) = (
708 $self->_limit_counter(
709 $branch_rules->{method}, { branchcode => $branchcode }
711 $self->_limit_counter(
712 $brw_rules->{method}, { borrowernumber => $patron->borrowernumber }
716 # Compare and return
717 # A limit of -1 means no limit exists.
718 # We return blocked if either branch limit or brw limit is reached.
719 if ( ( $branch_limit != -1 && $branch_limit <= $branch_count )
720 || ( $brw_limit != -1 && $brw_limit <= $brw_count ) ) {
721 return 0;
722 } else {
723 return 1;
727 sub _limit_counter {
728 my ( $self, $method, $target ) = @_;
730 # Establish parameters of counts
731 my $resultset;
732 if ($method && $method eq 'annual') {
733 $resultset = Koha::Illrequests->search({
734 -and => [
735 %{$target},
736 \"YEAR(placed) = YEAR(NOW())"
739 } else { # assume 'active'
740 # XXX: This status list is ugly. There should be a method in config
741 # to return these.
742 $where = { status => { -not_in => [ 'QUEUED', 'COMP' ] } };
743 $resultset = Koha::Illrequests->search({ %{$target}, %{$where} });
746 # Fetch counts
747 return $resultset->count;
750 =head3 requires_moderation
752 my $status = $illRequest->requires_moderation;
754 Return the name of the status if moderation by staff is required; or 0
755 otherwise.
757 =cut
759 sub requires_moderation {
760 my ( $self ) = @_;
761 my $require_moderation = {
762 'CANCREQ' => 'CANCREQ',
764 return $require_moderation->{$self->status};
767 =head3 generic_confirm
769 my $stage_summary = $illRequest->generic_confirm;
771 Handle the generic_confirm extended method. The first stage involves creating
772 a template email for the end user to edit in the browser. The second stage
773 attempts to submit the email.
775 =cut
777 sub generic_confirm {
778 my ( $self, $params ) = @_;
779 my $branch = Koha::Libraries->find($params->{current_branchcode})
780 || die "Invalid current branchcode. Are you logged in as the database user?";
781 if ( !$params->{stage}|| $params->{stage} eq 'init' ) {
782 my $draft->{subject} = "ILL Request";
783 $draft->{body} = <<EOF;
784 Dear Sir/Madam,
786 We would like to request an interlibrary loan for a title matching the
787 following description:
791 my $details = $self->metadata;
792 while (my ($title, $value) = each %{$details}) {
793 $draft->{body} .= " - " . $title . ": " . $value . "\n"
794 if $value;
796 $draft->{body} .= <<EOF;
798 Please let us know if you are able to supply this to us.
800 Kind Regards
804 my @address = map { $branch->$_ }
805 qw/ branchname branchaddress1 branchaddress2 branchaddress3
806 branchzip branchcity branchstate branchcountry branchphone
807 branchemail /;
808 my $address = "";
809 foreach my $line ( @address ) {
810 $address .= $line . "\n" if $line;
813 $draft->{body} .= $address;
815 my $partners = Koha::Patrons->search({
816 categorycode => $self->_config->partner_code
818 return {
819 error => 0,
820 status => '',
821 message => '',
822 method => 'generic_confirm',
823 stage => 'draft',
824 value => {
825 draft => $draft,
826 partners => $partners,
830 } elsif ( 'draft' eq $params->{stage} ) {
831 # Create the to header
832 my $to = $params->{partners};
833 $to =~ s/^\x00//; # Strip leading NULLs
834 $to =~ s/\x00/; /; # Replace others with '; '
835 die "No target email addresses found. Either select at least one partner or check your ILL partner library records." if ( !$to );
836 # Create the from, replyto and sender headers
837 my $from = $branch->branchemail;
838 my $replyto = $branch->branchreplyto || $from;
839 die "Your branch has no email address. Please set it."
840 if ( !$from );
841 # Create the email
842 my $message = Koha::Email->new;
843 my %mail = $message->create_message_headers(
845 to => $to,
846 from => $from,
847 replyto => $replyto,
848 subject => Encode::encode( "utf8", $params->{subject} ),
849 message => Encode::encode( "utf8", $params->{body} ),
850 contenttype => 'text/plain',
853 # Send it
854 my $result = sendmail(%mail);
855 if ( $result ) {
856 $self->status("GENREQ")->store;
857 return {
858 error => 0,
859 status => '',
860 message => '',
861 method => 'generic_confirm',
862 stage => 'commit',
863 next => 'illview',
865 } else {
866 return {
867 error => 1,
868 status => 'email_failed',
869 message => $Mail::Sendmail::error,
870 method => 'generic_confirm',
871 stage => 'draft',
874 } else {
875 die "Unknown stage, should not have happened."
879 =head3 id_prefix
881 my $prefix = $record->id_prefix;
883 Return the prefix appropriate for the current Illrequest as derived from the
884 borrower and branch associated with this request's Status, and the config
885 file.
887 =cut
889 sub id_prefix {
890 my ( $self ) = @_;
891 my $brw = $self->patron;
892 my $brw_cat = "dummy";
893 $brw_cat = $brw->categorycode
894 unless ( 'HASH' eq ref($brw) && $brw->{deleted} );
895 my $prefix = $self->getPrefix( {
896 brw_cat => $brw_cat,
897 branch => $self->branchcode,
898 } );
899 $prefix .= "-" if ( $prefix );
900 return $prefix;
903 =head3 _censor
905 my $params = $illRequest->_censor($params);
907 Return $params, modified to reflect our censorship requirements.
909 =cut
911 sub _censor {
912 my ( $self, $params ) = @_;
913 my $censorship = $self->_config->censorship;
914 $params->{censor_notes_staff} = $censorship->{censor_notes_staff}
915 if ( $params->{opac} );
916 $params->{display_reply_date} = ( $censorship->{censor_reply_date} ) ? 0 : 1;
918 return $params;
921 =head3 TO_JSON
923 $json = $illrequest->TO_JSON
925 Overloaded I<TO_JSON> method that takes care of inserting calculated values
926 into the unblessed representation of the object.
928 =cut
930 sub TO_JSON {
931 my ( $self, $embed ) = @_;
933 my $object = $self->SUPER::TO_JSON();
934 $object->{id_prefix} = $self->id_prefix;
936 if ( scalar (keys %$embed) ) {
937 # Augment the request response with patron details if appropriate
938 if ( $embed->{patron} ) {
939 my $patron = $self->patron;
940 $object->{patron} = {
941 firstname => $patron->firstname,
942 surname => $patron->surname,
943 cardnumber => $patron->cardnumber
946 # Augment the request response with metadata details if appropriate
947 if ( $embed->{metadata} ) {
948 $object->{metadata} = $self->metadata;
950 # Augment the request response with status details if appropriate
951 if ( $embed->{capabilities} ) {
952 $object->{capabilities} = $self->capabilities;
954 # Augment the request response with library details if appropriate
955 if ( $embed->{branch} ) {
956 $object->{branch} = Koha::Libraries->find(
957 $self->branchcode
958 )->TO_JSON;
962 return $object;
965 =head2 Internal methods
967 =head3 _type
969 =cut
971 sub _type {
972 return 'Illrequest';
975 =head1 AUTHOR
977 Alex Sassmannshausen <alex.sassmannshausen@ptfs-europe.com>
979 =cut