Bug 26896: Enable SIP option holds_block_checkin to actually block checkin of items...
[koha.git] / C4 / SIP / ILS / Transaction / Checkin.pm
1 #
2 # An object to handle checkin status
3 #
4
5 package C4::SIP::ILS::Transaction::Checkin;
6
7 use warnings;
8 use strict;
9
10 # use POSIX qw(strftime);
11
12 use C4::SIP::ILS::Transaction;
13
14 use C4::Circulation;
15 use C4::Debug;
16 use C4::Items qw( ModItemTransfer );
17 use C4::Reserves qw( ModReserveAffect );
18 use Koha::DateUtils qw( dt_from_string );
19 use Koha::Items;
20
21 use parent qw(C4::SIP::ILS::Transaction);
22
23 my %fields = (
24     magnetic => 0,
25     sort_bin => undef,
26     collection_code  => undef,
27     # 3M extensions:
28     call_number      => undef,
29     destination_loc  => undef,
30     alert_type       => undef,  # 00,01,02,03,04 or 99
31     hold_patron_id   => undef,
32     hold_patron_name => "",
33     hold             => undef,
34 );
35
36 sub new {
37     my $class = shift;
38     my $self = $class->SUPER::new();                # start with an ILS::Transaction object
39
40     foreach (keys %fields) {
41         $self->{_permitted}->{$_} = $fields{$_};    # overlaying _permitted
42     }
43
44     @{$self}{keys %fields} = values %fields;        # copying defaults into object
45     return bless $self, $class;
46 }
47
48 sub do_checkin {
49     my $self = shift;
50     my $branch = shift;
51     my $return_date = shift;
52     my $account = shift;
53
54     my $checked_in_ok     = $account->{checked_in_ok};
55     my $cv_triggers_alert = $account->{cv_triggers_alert};
56     my $holds_block_checkin  = $account->{holds_block_checkin};
57
58     if (!$branch) {
59         $branch = 'SIP2';
60     }
61     my $barcode = $self->{item}->id;
62
63     if ( $return_date ) {
64         $return_date =   substr( $return_date, 0, 4 )
65                        . '-'
66                        . substr( $return_date, 4, 2 )
67                        . '-'
68                        . substr( $return_date, 6, 2 )
69                        . q{ }
70                        . substr( $return_date, 12, 2 )
71                        . ':'
72                        . substr( $return_date, 14, 2 )
73                        . ':'
74                        . substr( $return_date, 16, 2 );
75         $return_date = dt_from_string($return_date);
76     }
77
78     my ( $return, $messages, $issue, $borrower );
79
80     my $item = Koha::Items->find( { barcode => $barcode } );
81
82     my $human_required = 0;
83     if (   C4::Context->preference("CircConfirmItemParts")
84         && defined($item)
85         && $item->materials )
86     {
87         $human_required                   = 1;
88         $messages->{additional_materials} = 1;
89     }
90
91     my $checkin_blocked_by_holds = $holds_block_checkin && $item->biblio->holds->count;
92
93     $debug and warn "do_checkin() calling AddReturn($barcode, $branch)";
94     ( $return, $messages, $issue, $borrower ) =
95       AddReturn( $barcode, $branch, undef, $return_date )
96       unless $human_required || $checkin_blocked_by_holds;
97
98     if ( $checked_in_ok ) {
99         delete $messages->{ItemLocationUpdated};
100         delete $messages->{NotIssued};
101         delete $messages->{LocalUse};
102         $return = 1 unless keys %$messages;
103     }
104
105     # biblionumber, biblioitemnumber, itemnumber
106     # borrowernumber, reservedate, branchcode
107     # cancellationdate, found, reservenotes, priority, timestamp
108     if ($messages->{additional_materials}) {
109         $self->alert_type('99');
110     }
111     if( $messages->{DataCorrupted} ) {
112         $self->alert_type('98');
113     }
114     if ($messages->{BadBarcode}) {
115         $self->alert_type('99');
116     }
117     if ($messages->{withdrawn}) {
118         $self->alert_type('99');
119     }
120     if ($messages->{WasLost}) {
121         $self->alert_type('99') if C4::Context->preference("BlockReturnOfLostItems");
122     }
123     if ($messages->{Wrongbranch}) {
124         $self->{item}->destination_loc($messages->{Wrongbranch}->{Rightbranch});
125         $self->alert_type('04');            # send to other branch
126     }
127     if ($messages->{WrongTransfer}) {
128         $self->{item}->destination_loc($messages->{WrongTransfer});
129         $self->alert_type('04');            # send to other branch
130     }
131     if ($messages->{NeedsTransfer}) {
132         $self->{item}->destination_loc($messages->{NeedsTransfer});
133         $self->alert_type('04');            # send to other branch
134     }
135     if ($messages->{WasTransfered}) { # set into transit so tell unit
136         $self->{item}->destination_loc($issue->item->homebranch);
137         $self->alert_type('04');            # send to other branch
138     }
139     if ($messages->{ResFound} || $checkin_blocked_by_holds ) {
140         if ($checkin_blocked_by_holds) {
141             $self->alert_type('99');
142             $return = 0;
143         } elsif ($branch eq $messages->{ResFound}->{branchcode}) {
144             $self->hold($messages->{ResFound});
145             $self->alert_type('01');
146             ModReserveAffect( $messages->{ResFound}->{itemnumber},
147                 $messages->{ResFound}->{borrowernumber}, 0, $messages->{ResFound}->{reserve_id});
148
149         } else {
150             $self->hold($messages->{ResFound});
151             $self->alert_type('02');
152             ModReserveAffect( $messages->{ResFound}->{itemnumber},
153                 $messages->{ResFound}->{borrowernumber}, 1, $messages->{ResFound}->{reserve_id});
154             ModItemTransfer( $messages->{ResFound}->{itemnumber},
155                 $branch,
156                 $messages->{ResFound}->{branchcode},
157                 $messages->{TransferTrigger},
158             );
159
160         }
161         $self->{item}->hold_patron_id( $messages->{ResFound}->{borrowernumber} );
162         $self->{item}->destination_loc( $messages->{ResFound}->{branchcode} );
163     }
164     # ignoring messages: NotIssued, WasTransfered
165
166     if ($cv_triggers_alert) {
167         $self->alert( defined $self->alert_type ); # Overwrites existing alert value, should set to 0 if there is no alert type
168     }
169     else {
170         $self->alert( !$return || defined $self->alert_type );
171     }
172
173     $self->ok($return);
174
175     return { messages => $messages };
176 }
177
178 sub resensitize {
179         my $self = shift;
180         unless ($self->{item}) {
181                 warn "resensitize(): no item found in object to resensitize";
182                 return;
183         }
184         return !$self->{item}->magnetic_media;
185 }
186
187 sub patron_id {
188         my $self = shift;
189         unless ($self->{patron}) {
190                 warn "patron_id(): no patron found in object";
191                 return;
192         }
193         return $self->{patron}->id;
194 }
195
196 1;