1 package OpenILS::SIP::Item;
2 use strict; use warnings;
4 use Sys::Syslog qw(syslog);
8 use OpenILS::SIP::Transaction;
9 use OpenILS::Application::AppUtils;
10 use OpenILS::Application::Circ::ScriptBuilder;
12 use OpenILS::Const qw/:const/;
13 use OpenSRF::Utils qw/:datetime/;
14 use DateTime::Format::ISO8601;
15 use OpenSRF::Utils::SettingsClient;
16 my $U = 'OpenILS::Application::AppUtils';
21 # 1 means read/write Actually, gloves are off. Set what you like.
25 # sip_media_type => 0,
26 sip_item_properties => 0,
27 # magnetic_media => 0,
28 permanent_location => 0,
29 current_location => 0,
35 hold_patron_bcode => 0,
36 hold_patron_name => 0,
53 sub DESTROY { } # keeps AUTOLOAD from catching inherent DESTROY calls
57 my $class = ref($self) or croak "$self is not an object";
62 unless (exists $fields{$name}) {
63 croak "Cannot access '$name' field of class '$class'";
67 # $fields{$name} or croak "Field '$name' of class '$class' is READ ONLY."; # nah, go ahead
68 return $self->{$name} = shift;
70 return $self->{$name};
76 my ($class, $item_id) = @_;
77 my $type = ref($class) || $class;
78 my $self = bless( {}, $type );
80 syslog('LOG_DEBUG', "OILS: Loading item $item_id...");
81 return undef unless $item_id;
83 my $e = OpenILS::SIP->editor();
85 my $copy = $e->search_asset_copy(
87 { barcode => $item_id, deleted => 'f' },
91 acp => [ 'circ_lib', 'call_number', 'status' ],
92 acn => [ 'owning_lib', 'record' ],
102 syslog("LOG_DEBUG", "OILS: Item '%s' : not found", $item_id);
106 my ($circ) = $U->fetch_open_circulation($copy->id);
108 # if i am checked out, set $self->{patron} to the user's barcode
109 my $user = $e->retrieve_actor_user(
112 { flesh => 1, flesh_fields => { "au" => [ 'card' ] } }
116 my $bc = ($user) ? $user->card->barcode : "";
117 $self->{patron} = $bc;
118 $self->{patron_object} = $user;
120 syslog('LOG_DEBUG', "OILS: Open circulation exists on $item_id : user = $bc");
123 $self->{id} = $item_id;
124 $self->{copy} = $copy;
125 $self->{volume} = $copy->call_number;
126 $self->{record} = $copy->call_number->record;
127 $self->{mods} = $U->record_to_mvr($self->{record}) if $self->{record}->marc;
129 syslog("LOG_DEBUG", "OILS: Item('$item_id'): found with title '%s'", $self->title_id);
131 my $config = OpenILS::SIP->config(); # FIXME : will not always match!
133 my $legacy = $config->{implementation_config}->{legacy_script_support} || undef;
134 if( defined $legacy ) {
135 $self->{legacy_script_support} = ($legacy =~ /t(rue)?/io) ? 1 : 0;
136 syslog("LOG_DEBUG", "legacy_script_support is set in SIP config: " . $self->{legacy_script_support});
138 my $lss = OpenSRF::Utils::SettingsClient->new->config_value(
139 apps => 'open-ils.circ',
140 app_settings => 'legacy_script_support'
142 $self->{legacy_script_support} = ($lss =~ /t(rue)?/io) ? 1 : 0;
143 syslog("LOG_DEBUG", "legacy_script_support is set in SRF config: " . $self->{legacy_script_support});
149 sub run_attr_script {
151 return 1 if $self->{ran_script};
152 $self->{ran_script} = 1;
154 if($self->{legacy_script_support}){
156 syslog('LOG_DEBUG', "Legacy script support is ON");
157 my $config = OpenILS::SIP->config();
158 my $path = $config->{implementation_config}->{scripts}->{path};
159 my $item_config_script = $config->{implementation_config}->{scripts}->{item_config};
161 $path = ref($path) eq 'ARRAY' ? $path : [$path];
162 my $path_str = join(", ", @$path);
164 syslog('LOG_DEBUG', "OILS: Script path = [$path_str], Item config script = $item_config_script");
166 my $runner = OpenILS::Application::Circ::ScriptBuilder->build({
167 copy => $self->{copy},
168 editor => OpenILS::SIP->editor(),
171 $runner->add_path($_) for @$path;
172 $runner->load($item_config_script);
174 unless( $self->{item_config_result} = $runner->run ) { # assignment, not comparison
176 warn "Item config script [$path_str : $item_config_script] failed to run: $@\n";
177 syslog('LOG_ERR', "OILS: Item config script [$path_str : $item_config_script] failed to run: $@");
185 # use the in-db circ modifier configuration
186 my $config = {magneticMedia => 'f', SIPMediaType => '001'}; # defaults
187 my $mod = $self->{copy}->circ_modifier;
190 my $mod_obj = OpenILS::SIP->editor()->search_config_circ_modifier($mod);
192 $config->{magneticMedia} = $mod_obj->magnetic_media;
193 $config->{SIPMediaType} = $mod_obj->sip2_media_type;
197 $self->{item_config_result} = { item_config => $config };
209 return 0 unless $self->run_attr_script;
210 my $mag = $self->{item_config_result}->{item_config}->{magneticMedia} || '';
211 syslog('LOG_DEBUG', "OILS: magnetic = $mag");
212 return ($mag and $mag =~ /t(rue)?/io) ? 1 : 0;
217 return 0 unless $self->run_attr_script;
218 my $media = $self->{item_config_result}->{item_config}->{SIPMediaType} || '';
219 syslog('LOG_DEBUG', "OILS: media type = $media");
220 return ($media) ? $media : '001';
225 my $t = ($self->{mods}) ? $self->{mods}->title : $self->{copy}->dummy_title;
226 return OpenILS::SIP::clean_text($t);
229 sub permanent_location {
231 return OpenILS::SIP::clean_text($self->{volume}->owning_lib->name);
234 sub current_location {
236 return OpenILS::SIP::clean_text($self->{copy}->circ_lib->name);
245 # 05 Charged; not to be recalled until earliest recall date
248 # 08 Waiting on hold shelf
249 # 09 Waiting to be re-shelved
250 # 10 In transit between library locations
251 # 11 Claimed returned
254 sub sip_circulation_status {
256 my $stat = $self->{copy}->status->id;
258 return '02' if $stat == OILS_COPY_STATUS_ON_ORDER;
259 return '03' if $stat == OILS_COPY_STATUS_AVAILABLE;
260 return '04' if $stat == OILS_COPY_STATUS_CHECKED_OUT;
261 return '06' if $stat == OILS_COPY_STATUS_IN_PROCESS;
262 return '08' if $stat == OILS_COPY_STATUS_ON_HOLDS_SHELF;
263 return '09' if $stat == OILS_COPY_STATUS_RESHELVING;
264 return '10' if $stat == OILS_COPY_STATUS_IN_TRANSIT;
265 return '12' if $stat == OILS_COPY_STATUS_LOST;
266 return '13' if $stat == OILS_COPY_STATUS_MISSING;
271 sub sip_security_marker {
272 return '02'; # FIXME? 00-other; 01-None; 02-Tattle-Tape Security Strip (3M); 03-Whisper Tape (3M)
276 return '01'; # FIXME? 01-09 enumerated in spec. We just use O1-other/unknown.
287 return OpenILS::SIP->config()->{implementation_config}->{currency};
292 return OpenILS::SIP::clean_text($self->{volume}->owning_lib->name);
300 sub hold_queue_position { # TODO
301 my ($self, $patron_id) = @_;
308 # this should force correct circ fetching
309 require OpenILS::Utils::CStoreEditor;
310 my $e = OpenILS::Utils::CStoreEditor->new(xact => 1);
311 #my $e = OpenILS::SIP->editor();
313 my $circ = $e->search_action_circulation(
314 { target_copy => $self->{copy}->id, checkin_time => undef } )->[0];
319 syslog('LOG_INFO', "OILS: No open circ found for copy");
323 my $due = OpenILS::SIP->format_date($circ->due_date, 'due');
324 syslog('LOG_DEBUG', "OILS: Found item due date = $due");
328 sub recall_date { # TODO
333 sub hold_pickup_date { # TODO
338 # message to display on console
341 return OpenILS::SIP::clean_text($self->{screen_msg}) || '';
348 return OpenILS::SIP::clean_text($self->{print_line}) || '';
352 # An item is available for a patron if
353 # 1) It's not checked out and (there's no hold queue OR patron
354 # is at the front of the queue)
356 # 2) It's checked out to the patron and there's no hold queue
358 my ($self, $for_patron) = @_;
360 my $stat = $self->{copy}->status->id;
362 $stat == OILS_COPY_STATUS_AVAILABLE or
363 $stat == OILS_COPY_STATUS_RESHELVING;