1 package OpenILS::Application::Storage::Publisher::asset;
2 use base qw/OpenILS::Application::Storage/;
3 #use OpenILS::Application::Storage::CDBI::asset;
4 #use OpenILS::Utils::Fieldmapper;
5 use OpenSRF::Utils::Logger qw/:level/;
6 use OpenSRF::EX qw/:try/;
10 my $log = 'OpenSRF::Utils::Logger';
15 #our $_default_subfield_map = {
19 # circulating_lib => $cl,
20 # copy_location => $sl,
21 # copy_number => $num,
24 # create_date => $date,
26 # legacy_item_type => $it,
27 # legacy_item_cat_1 => $ic1,
28 # legacy_item_cat_2 => $ic2,
31 sub import_xml_holdings {
39 my $date_format = shift || 'mm/dd/yyyy';
41 my $r = MARC::Record->new_from_xml($xml);
43 for my $f ( $r->fields( $tag ) ) {
44 next unless ($f->subfield( $map->{owning_lib} ));
49 $ol = actor::org_unit->search( shortname => $f->subfield( $map->{owning_lib} ) )->next->id;
51 $log->debug('Could not find library with shortname ['.$f->subfield( $map->{owning_lib} ).'] : '. shift(), ERROR);
55 $cl = actor::org_unit->search( shortname => $f->subfield( $map->{circulating_lib} ) )->next->id;
57 $log->debug('Could not find library with shortname ['.$f->subfield( $map->{circulating_lib} ).'] : '. shift(), ERROR);
60 next unless ($ol && $cl);
64 $cn = asset::call_number->find_or_create(
65 { label => $f->subfield( $map->{call_number} ),
73 $log->debug('Could not find or create callnumber ['.$f->subfield( $map->{call_number} ).'] : '. shift(), ERROR);
78 my $create_date = $f->subfield( $map->{create_date} );
81 if ($date_format eq 'mm/dd/yyyy') {
82 ($m,$d,$y) = split '/', $create_date;
84 } elsif ($date_format eq 'dd/mm/yyyy') {
85 ($d,$m,$y) = split '/', $create_date;
87 } elsif ($date_format eq 'mm-dd-yyyy') {
88 ($m,$d,$y) = split '-', $create_date;
90 } elsif ($date_format eq 'dd-mm-yyyy') {
91 ($d,$m,$y) = split '-', $create_date;
93 } elsif ($date_format eq 'yyyy-mm-dd') {
94 ($y,$m,$d) = split '-', $create_date;
96 } elsif ($date_format eq 'yyyy/mm/dd') {
97 ($y,$m,$d) = split '/', $create_date;
101 (undef,undef,undef,$d,$m,$y) = localtime;
106 my $price = $f->subfield( $map->{price} );
107 $price =~ s/[^0-9\.]+//gso;
112 { circ_lib => actor::org_unit->search( shortname => $f->subfield( $map->{circulating_lib} ) )->next->id,
113 copy_number => $f->subfield( $map->{copy_number} ),
115 barcode => $f->subfield( $map->{barcode} ),
120 create_date => sprintf('%04d-%02d-%02d',$y,$m,$d),
124 $log->debug('Could not create copy ['.$f->subfield( $map->{barcode} ).'] : '. shift(), ERROR);
130 __PACKAGE__->register_method(
131 method => 'import_xml_holdings',
132 api_name => 'open-ils.storage.asset.holdings.import.xml',
138 # see /home/miker/cn_browse-test.sql for page up and down sql ...
141 sub cn_browse_pagedown {
147 my $cn = uc($args{label});
148 my $org = $args{org_unit};
149 my $depth = $args{depth};
150 my $boundry_id = $args{boundry_id};
151 my $size = $args{page_size} || 20;
154 my $table = asset::call_number->table;
156 my $descendants = "actor.org_unit_descendants($org)";
157 if (defined $depth) {
158 $descendants = "actor.org_unit_descendants($org,$depth)";
170 on (d.id = cn.owning_lib)
173 or ( cn.id > ? and upper(label) = ? )
174 order by upper(label), 4, 2
178 my $sth = asset::call_number->db_Main->prepare($sql);
179 $sth->execute($cn, $boundry_id, $cn);
180 while ( my @row = $sth->fetchrow_array ) {
181 $client->respond([@row]);
187 __PACKAGE__->register_method(
188 method => 'cn_browse_pagedown',
189 api_name => 'open-ils.storage.asset.call_number.browse.page_down',
194 sub cn_browse_pageup {
200 my $cn = uc($args{label});
201 my $org = $args{org_unit};
202 my $depth = $args{depth};
203 my $boundry_id = $args{boundry_id};
204 my $size = $args{page_size} || 20;
207 my $table = asset::call_number->table;
209 my $descendants = "actor.org_unit_descendants($org)";
210 if (defined $depth) {
211 $descendants = "actor.org_unit_descendants($org,$depth)";
224 on (d.id = cn.owning_lib)
227 or ( cn.id < ? and upper(label) = ? )
228 order by upper(label) desc, 4 desc, 2 desc
234 my $sth = asset::call_number->db_Main->prepare($sql);
235 $sth->execute($cn, $boundry_id, $cn);
236 while ( my @row = $sth->fetchrow_array ) {
237 $client->respond([@row]);
243 __PACKAGE__->register_method(
244 method => 'cn_browse_pageup',
245 api_name => 'open-ils.storage.asset.call_number.browse.page_up',
250 sub cn_browse_target {
256 my $cn = uc($args{label});
257 my $org = $args{org_unit};
258 my $depth = $args{depth};
259 my $size = $args{page_size} || 20;
260 my $topsize = $size / 2;
261 $topsize = int($topsize);
262 $bottomsize = $size - $topsize;
264 my $table = asset::call_number->table;
266 my $descendants = "actor.org_unit_descendants($org)";
267 if (defined $depth) {
268 $descendants = "actor.org_unit_descendants($org,$depth)";
271 my $top_sql = <<" SQL";
281 on (d.id = cn.owning_lib)
284 order by upper(label) desc, 4 desc, 2 desc
290 my $bottom_sql = <<" SQL";
299 on (d.id = cn.owning_lib)
302 order by upper(label),4,2
306 my $sth = asset::call_number->db_Main->prepare($top_sql);
308 while ( my @row = $sth->fetchrow_array ) {
309 $client->respond([@row]);
313 $sth = asset::call_number->db_Main->prepare($bottom_sql);
315 while ( my @row = $sth->fetchrow_array ) {
316 $client->respond([@row]);
322 __PACKAGE__->register_method(
323 method => 'cn_browse_target',
324 api_name => 'open-ils.storage.asset.call_number.browse.target',
337 return unless ($cp && $org);
339 $cp = $cp->id if (ref $cp);
340 $cp = asset::copy->retrieve($cp);
342 my $ol = $cp->call_number->owning_lib;
344 return asset::copy->db_Main->selectcol_arrayref('SELECT actor.org_unit_proximity(?,?)',{},"$ol","$org")->[0];
346 __PACKAGE__->register_method(
347 method => 'copy_proximity',
348 api_name => 'open-ils.storage.asset.copy.proximity',
353 sub asset_copy_location_all {
357 for my $rec ( asset::copy_location->retrieve_all ) {
358 $client->respond( $rec->to_fieldmapper );
363 __PACKAGE__->register_method(
364 method => 'asset_copy_location_all',
365 api_name => 'open-ils.storage.direct.asset.copy_location.retrieve.all',
370 # XXX arg, with the descendancy SPs...
371 sub ranged_asset_copy_location {
376 my $ctable = asset::copy_location->table;
378 my $descendants = defined($binds[1]) ?
379 "actor.org_unit_full_path(?, ?)" :
380 "actor.org_unit_full_path(?)" ;
387 ON (d.id = c.owning_lib)
390 my $sth = asset::copy_location->db_Main->prepare($sql);
391 $sth->execute(@binds);
393 while ( my $rec = $sth->fetchrow_hashref ) {
395 my $cnct = new Fieldmapper::asset::copy_location;
396 map {$cnct->$_($$rec{$_})} keys %$rec;
397 $client->respond( $cnct );
402 __PACKAGE__->register_method(
403 method => 'ranged_asset_copy_location',
404 api_name => 'open-ils.storage.ranged.asset.copy_location.retrieve',
415 return undef unless (@ids);
417 @ids = ($ids[0]) unless ($self->api_name =~ /batch/o);
419 for my $id ( @ids ) {
421 my $cp = asset::copy->retrieve($id);
424 my $cp_fm = $cp->to_fieldmapper;
425 $cp_fm->circ_lib( $cp->circ_lib->to_fieldmapper );
426 $cp_fm->location( $cp->location->to_fieldmapper );
427 $cp_fm->status( $cp->status->to_fieldmapper );
428 $cp_fm->stat_cat_entries( [ map { $_->to_fieldmapper } $cp->stat_cat_entries ] );
430 $client->respond( $cp_fm );
435 __PACKAGE__->register_method(
436 api_name => 'open-ils.storage.fleshed.asset.copy.batch.retrieve',
437 method => 'fleshed_copy',
441 __PACKAGE__->register_method(
442 api_name => 'open-ils.storage.fleshed.asset.copy.retrieve',
443 method => 'fleshed_copy',
447 sub fleshed_copy_by_barcode {
452 my ($cp) = asset::copy->search( { barcode => $bc } );
454 return undef unless ($cp);
456 my $cp_fm = $cp->to_fieldmapper;
457 $cp_fm->circ_lib( $cp->circ_lib->to_fieldmapper );
458 $cp_fm->location( $cp->location->to_fieldmapper );
459 $cp_fm->status( $cp->status->to_fieldmapper );
463 __PACKAGE__->register_method(
464 api_name => 'open-ils.storage.fleshed.asset.copy.search.barcode',
465 method => 'fleshed_copy_by_barcode',
471 #XXX Fix stored proc calls
472 sub fleshed_asset_stat_cat {
477 @list = ($list[0]) unless ($self->api_name =~ /batch/o);
479 my $cat = asset::stat_cat->retrieve($sc);
483 my $sc_fm = $cat->to_fieldmapper;
484 $sc_fm->entries( [ map { $_->to_fieldmapper } $cat->entries ] );
485 $client->respond( $sc_fm );
490 __PACKAGE__->register_method(
491 api_name => 'open-ils.storage.fleshed.asset.stat_cat.retrieve',
493 method => 'fleshed_asset_stat_cat',
496 __PACKAGE__->register_method(
497 api_name => 'open-ils.storage.fleshed.asset.stat_cat.retrieve.batch',
500 method => 'fleshed_asset_stat_cat',
504 #XXX Fix stored proc calls
505 sub ranged_asset_stat_cat {
510 return undef unless ($ou);
511 my $s_table = asset::stat_cat->table;
513 my $select = <<" SQL";
516 JOIN actor.org_unit_full_path(?) p ON (p.id = s.owner)
521 $fleshed = 1 if ($self->api_name =~ /fleshed/o);
523 my $sth = asset::stat_cat->db_Main->prepare_cached($select);
526 for my $sc ( map { asset::stat_cat->construct($_) } $sth->fetchall_hash ) {
527 my $sc_fm = $sc->to_fieldmapper;
529 [ $self->method_lookup( 'open-ils.storage.ranged.asset.stat_cat_entry.search.stat_cat' )->run($ou,$sc->id) ]
531 $client->respond( $sc_fm );
536 __PACKAGE__->register_method(
537 api_name => 'open-ils.storage.ranged.fleshed.asset.stat_cat.all',
540 method => 'ranged_asset_stat_cat',
543 __PACKAGE__->register_method(
544 api_name => 'open-ils.storage.ranged.asset.stat_cat.all',
547 method => 'ranged_asset_stat_cat',
551 #XXX Fix stored proc calls
552 sub multiranged_asset_stat_cat {
557 return undef unless (defined($ous) and @$ous);
558 my $s_table = asset::stat_cat->table;
560 my $select = <<" SQL";
563 WHERE s.owner IN ( XXX )
567 my $collector = ' INTERSECT ';
568 my $entry_method = 'open-ils.storage.multiranged.intersect.asset.stat_cat_entry.search.stat_cat';
569 if ($self->api_name =~ /union/o) {
570 $collector = ' UNION ';
571 $entry_method = 'open-ils.storage.multiranged.union.asset.stat_cat_entry.search.stat_cat';
574 my $binds = join($collector, map { 'SELECT id FROM actor.org_unit_full_path(?)' } grep {defined} @$ous);
575 $select =~ s/XXX/$binds/so;
578 $fleshed = 1 if ($self->api_name =~ /fleshed/o);
580 my $sth = asset::stat_cat->db_Main->prepare_cached($select);
581 $sth->execute(map { "$_" } grep {defined} @$ous);
583 for my $sc ( map { asset::stat_cat->construct($_) } $sth->fetchall_hash ) {
584 my $sc_fm = $sc->to_fieldmapper;
586 [ $self->method_lookup( $entry_method )->run($ous, $sc->id) ]
588 $client->respond( $sc_fm );
593 __PACKAGE__->register_method(
594 api_name => 'open-ils.storage.multiranged.intersect.fleshed.asset.stat_cat.all',
597 method => 'multiranged_asset_stat_cat',
599 __PACKAGE__->register_method(
600 api_name => 'open-ils.storage.multiranged.union.fleshed.asset.stat_cat.all',
603 method => 'multiranged_asset_stat_cat',
606 #XXX Fix stored proc calls
607 sub ranged_asset_stat_cat_entry {
613 return undef unless ($ou);
614 my $s_table = asset::stat_cat_entry->table;
616 my $select = <<" SQL";
619 JOIN actor.org_unit_full_path(?) p ON (p.id = s.owner)
624 my $sth = asset::stat_cat->db_Main->prepare_cached($select);
625 $sth->execute($ou,$sc);
627 for my $sce ( map { asset::stat_cat_entry->construct($_) } $sth->fetchall_hash ) {
628 $client->respond( $sce->to_fieldmapper );
633 __PACKAGE__->register_method(
634 api_name => 'open-ils.storage.ranged.asset.stat_cat_entry.search.stat_cat',
637 method => 'ranged_asset_stat_cat_entry',
640 #XXX Fix stored proc calls
641 sub multiranged_asset_stat_cat_entry {
647 return undef unless (defined($ous) and @$ous);
648 my $s_table = asset::stat_cat_entry->table;
650 my $collector = ' INTERSECT ';
651 $collector = ' UNION ' if ($self->api_name =~ /union/o);
653 my $select = <<" SQL";
656 WHERE s.owner IN ( XXX ) and s.stat_cat = ?
660 my $binds = join($collector, map { 'SELECT id FROM actor.org_unit_full_path(?)' } grep {defined} @$ous);
661 $select =~ s/XXX/$binds/so;
663 my $sth = asset::stat_cat->db_Main->prepare_cached($select);
664 $sth->execute(map {"$_"} @$ous,$sc);
666 for my $sce ( map { asset::stat_cat_entry->construct($_) } $sth->fetchall_hash ) {
667 $client->respond( $sce->to_fieldmapper );
672 __PACKAGE__->register_method(
673 api_name => 'open-ils.storage.multiranged.intersect.asset.stat_cat_entry.search.stat_cat',
676 method => 'multiranged_asset_stat_cat_entry',
678 __PACKAGE__->register_method(
679 api_name => 'open-ils.storage.multiranged.union.asset.stat_cat_entry.search.stat_cat',
682 method => 'multiranged_asset_stat_cat_entry',
691 my $depth = shift || 0;
696 ->selectcol_arrayref(
697 'SELECT id FROM actor.org_unit_descendants(?,?)',
703 return undef unless ($ou_list and @$ou_list);
705 $cn = asset::call_number->retrieve( $cn );
706 return undef unless ($cn);
708 my $call_number = $cn->to_fieldmapper;
709 $call_number->copies([]);
711 $call_number->record( $cn->record->to_fieldmapper );
712 $call_number->record->fixed_fields( $cn->record->record_descriptor->next->to_fieldmapper );
714 for my $cp ( $cn->copies(circ_lib => $ou_list) ) {
715 my $copy = $cp->to_fieldmapper;
716 $copy->status( $cp->status->to_fieldmapper );
717 $copy->location( $cp->status->to_fieldmapper );
719 push @{ $call_number->copies }, $copy;
724 __PACKAGE__->register_method(
725 api_name => 'open-ils.storage.asset.call_number.ranged_tree',
726 method => 'cn_ranged_tree',