1 package OpenILS::Application::Storage::Publisher::asset;
2 use base qw/OpenILS::Application::Storage/;
3 #use OpenILS::Application::Storage::CDBI::asset;
4 #use OpenSRF::Utils::Logger qw/:level/;
5 #use OpenILS::Utils::Fieldmapper;
7 #my $log = 'OpenSRF::Utils::Logger';
12 #our $_default_subfield_map = {
16 # circulating_lib => $cl,
17 # copy_location => $sl,
18 # copy_number => $num,
21 # create_date => $date,
23 # legacy_item_type => $it,
24 # legacy_item_cat_1 => $ic1,
25 # legacy_item_cat_2 => $ic2,
28 sub import_xml_holdings {
36 my $date_format = shift || 'mm/dd/yyyy';
38 my $r = MARC::Record->new_from_xml($xml);
40 for my $f ( $r->fields( $tag ) ) {
41 next unless ($f->subfield( $map->{owning_lib} ));
43 my $ol = actor::org_unit->search( shortname => $f->subfield( $map->{owning_lib} ) )->next->id;
44 my $cl = actor::org_unit->search( shortname => $f->subfield( $map->{circulating_lib} ) )->next->id;
46 my $cn = asset::call_number->find_or_create(
47 { label => $f->subfield( $map->{call_number} ),
55 my $create_date = $f->subfield( $map->{create_date} );
58 if ($date_format eq 'mm/dd/yyyy') {
59 ($m,$d,$y) = split '/', $create_date;
61 } elsif ($date_format eq 'dd/mm/yyyy') {
62 ($d,$m,$y) = split '/', $create_date;
64 } elsif ($date_format eq 'mm-dd-yyyy') {
65 ($m,$d,$y) = split '-', $create_date;
67 } elsif ($date_format eq 'dd-mm-yyyy') {
68 ($d,$m,$y) = split '-', $create_date;
70 } elsif ($date_format eq 'yyyy-mm-dd') {
71 ($y,$m,$d) = split '-', $create_date;
73 } elsif ($date_format eq 'yyyy/mm/dd') {
74 ($y,$m,$d) = split '-', $create_date;
77 my $price = $f->subfield( $map->{price} );
78 $price =~ s/[^0-9\.]+//gso;
82 { circ_lib => actor::org_unit->search( shortname => $f->subfield( $map->{circulating_lib} ) )->next->id,
83 copy_number => $f->subfield( $map->{copy_number} ),
85 barcode => $f->subfield( $map->{barcode} ),
90 create_date => sprintf('%04d-%02d-%02d',$y,$m,$d),
97 __PACKAGE__->register_method(
98 method => 'import_xml_holdings',
99 api_name => 'open-ils.storage.asset.holdings.import.xml',
105 # see /home/miker/cn_browse-test.sql for page up and down sql ...
108 sub cn_browse_pagedown {
114 my $cn = uc($args{label});
115 my $org = $args{org_unit};
116 my $depth = $args{depth};
117 my $boundry_id = $args{boundry_id};
118 my $size = $args{page_size} || 20;
121 my $table = asset::call_number->table;
123 my $descendants = "actor.org_unit_descendants($org)";
124 if (defined $depth) {
125 $descendants = "actor.org_unit_descendants($org,$depth)";
137 on (d.id = cn.owning_lib)
140 or ( cn.id > ? and upper(label) = ? )
141 order by upper(label), 4, 2
145 my $sth = asset::call_number->db_Main->prepare($sql);
146 $sth->execute($cn, $boundry_id, $cn);
147 while ( my @row = $sth->fetchrow_array ) {
148 $client->respond([@row]);
154 __PACKAGE__->register_method(
155 method => 'cn_browse_pagedown',
156 api_name => 'open-ils.storage.asset.call_number.browse.page_down',
161 sub cn_browse_pageup {
167 my $cn = uc($args{label});
168 my $org = $args{org_unit};
169 my $depth = $args{depth};
170 my $boundry_id = $args{boundry_id};
171 my $size = $args{page_size} || 20;
174 my $table = asset::call_number->table;
176 my $descendants = "actor.org_unit_descendants($org)";
177 if (defined $depth) {
178 $descendants = "actor.org_unit_descendants($org,$depth)";
191 on (d.id = cn.owning_lib)
194 or ( cn.id < ? and upper(label) = ? )
195 order by upper(label) desc, 4 desc, 2 desc
201 my $sth = asset::call_number->db_Main->prepare($sql);
202 $sth->execute($cn, $boundry_id, $cn);
203 while ( my @row = $sth->fetchrow_array ) {
204 $client->respond([@row]);
210 __PACKAGE__->register_method(
211 method => 'cn_browse_pageup',
212 api_name => 'open-ils.storage.asset.call_number.browse.page_up',
217 sub cn_browse_target {
223 my $cn = uc($args{label});
224 my $org = $args{org_unit};
225 my $depth = $args{depth};
226 my $size = $args{page_size} || 20;
227 my $topsize = $size / 2;
228 $topsize = int($topsize);
229 $bottomsize = $size - $topsize;
231 my $table = asset::call_number->table;
233 my $descendants = "actor.org_unit_descendants($org)";
234 if (defined $depth) {
235 $descendants = "actor.org_unit_descendants($org,$depth)";
238 my $top_sql = <<" SQL";
248 on (d.id = cn.owning_lib)
251 order by upper(label) desc, 4 desc, 2 desc
257 my $bottom_sql = <<" SQL";
266 on (d.id = cn.owning_lib)
269 order by upper(label),4,2
273 my $sth = asset::call_number->db_Main->prepare($top_sql);
275 while ( my @row = $sth->fetchrow_array ) {
276 $client->respond([@row]);
280 $sth = asset::call_number->db_Main->prepare($bottom_sql);
282 while ( my @row = $sth->fetchrow_array ) {
283 $client->respond([@row]);
289 __PACKAGE__->register_method(
290 method => 'cn_browse_target',
291 api_name => 'open-ils.storage.asset.call_number.browse.target',
304 return unless ($cp && $org);
306 $cp = $cp->id if (ref $cp);
307 $cp = asset::copy->retrieve($cp);
309 my $ol = $cp->call_number->owning_lib;
311 return asset::copy->db_Main->selectcol_arrayref('SELECT actor.org_unit_proximity(?,?)',{},"$ol","$org")->[0];
313 __PACKAGE__->register_method(
314 method => 'copy_proximity',
315 api_name => 'open-ils.storage.asset.copy.proximity',
320 sub asset_copy_location_all {
324 for my $rec ( asset::copy_location->retrieve_all ) {
325 $client->respond( $rec->to_fieldmapper );
330 __PACKAGE__->register_method(
331 method => 'asset_copy_location_all',
332 api_name => 'open-ils.storage.direct.asset.copy_location.retrieve.all',
337 # XXX arg, with the descendancy SPs...
338 sub ranged_asset_copy_location {
343 my $ctable = asset::copy_location->table;
345 my $descendants = defined($binds[1]) ?
346 "actor.org_unit_full_path(?, ?)" :
347 "actor.org_unit_full_path(?)" ;
354 ON (d.id = c.owning_lib)
357 my $sth = asset::copy_location->db_Main->prepare($sql);
358 $sth->execute(@binds);
360 while ( my $rec = $sth->fetchrow_hashref ) {
362 my $cnct = new Fieldmapper::asset::copy_location;
363 map {$cnct->$_($$rec{$_})} keys %$rec;
364 $client->respond( $cnct );
369 __PACKAGE__->register_method(
370 method => 'ranged_asset_copy_location',
371 api_name => 'open-ils.storage.ranged.asset.copy_location.retrieve',
382 return undef unless (@ids);
384 @ids = ($ids[0]) unless ($self->api_name =~ /batch/o);
386 for my $id ( @ids ) {
388 my $cp = asset::copy->retrieve($id);
391 my $cp_fm = $cp->to_fieldmapper;
392 $cp_fm->circ_lib( $cp->circ_lib->to_fieldmapper );
393 $cp_fm->location( $cp->location->to_fieldmapper );
394 $cp_fm->status( $cp->status->to_fieldmapper );
395 $cp_fm->stat_cat_entries( [ map { $_->to_fieldmapper } $cp->stat_cat_entries ] );
397 $client->respond( $cp_fm );
402 __PACKAGE__->register_method(
403 api_name => 'open-ils.storage.fleshed.asset.copy.batch.retrieve',
404 method => 'fleshed_copy',
408 __PACKAGE__->register_method(
409 api_name => 'open-ils.storage.fleshed.asset.copy.retrieve',
410 method => 'fleshed_copy',
414 sub fleshed_copy_by_barcode {
419 my ($cp) = asset::copy->search( { barcode => $bc } );
421 return undef unless ($cp);
423 my $cp_fm = $cp->to_fieldmapper;
424 $cp_fm->circ_lib( $cp->circ_lib->to_fieldmapper );
425 $cp_fm->location( $cp->location->to_fieldmapper );
426 $cp_fm->status( $cp->status->to_fieldmapper );
430 __PACKAGE__->register_method(
431 api_name => 'open-ils.storage.fleshed.asset.copy.search.barcode',
432 method => 'fleshed_copy_by_barcode',
438 #XXX Fix stored proc calls
439 sub fleshed_asset_stat_cat {
444 @list = ($list[0]) unless ($self->api_name =~ /batch/o);
446 my $cat = asset::stat_cat->retrieve($sc);
450 my $sc_fm = $cat->to_fieldmapper;
451 $sc_fm->entries( [ map { $_->to_fieldmapper } $cat->entries ] );
452 $client->respond( $sc_fm );
457 __PACKAGE__->register_method(
458 api_name => 'open-ils.storage.fleshed.asset.stat_cat.retrieve',
460 method => 'fleshed_asset_stat_cat',
463 __PACKAGE__->register_method(
464 api_name => 'open-ils.storage.fleshed.asset.stat_cat.retrieve.batch',
467 method => 'fleshed_asset_stat_cat',
471 #XXX Fix stored proc calls
472 sub ranged_asset_stat_cat {
477 return undef unless ($ou);
478 my $s_table = asset::stat_cat->table;
480 my $select = <<" SQL";
483 JOIN actor.org_unit_full_path(?) p ON (p.id = s.owner)
488 $fleshed = 1 if ($self->api_name =~ /fleshed/o);
490 my $sth = asset::stat_cat->db_Main->prepare_cached($select);
493 for my $sc ( map { asset::stat_cat->construct($_) } $sth->fetchall_hash ) {
494 my $sc_fm = $sc->to_fieldmapper;
496 [ $self->method_lookup( 'open-ils.storage.ranged.asset.stat_cat_entry.search.stat_cat' )->run($ou,$sc->id) ]
498 $client->respond( $sc_fm );
503 __PACKAGE__->register_method(
504 api_name => 'open-ils.storage.ranged.fleshed.asset.stat_cat.all',
507 method => 'ranged_asset_stat_cat',
510 __PACKAGE__->register_method(
511 api_name => 'open-ils.storage.ranged.asset.stat_cat.all',
514 method => 'ranged_asset_stat_cat',
518 #XXX Fix stored proc calls
519 sub multiranged_asset_stat_cat {
524 return undef unless (defined($ous) and @$ous);
525 my $s_table = asset::stat_cat->table;
527 my $select = <<" SQL";
530 WHERE s.owner IN ( XXX )
534 my $collector = ' INTERSECT ';
535 my $entry_method = 'open-ils.storage.multiranged.intersect.asset.stat_cat_entry.search.stat_cat';
536 if ($self->api_name =~ /union/o) {
537 $collector = ' UNION ';
538 $entry_method = 'open-ils.storage.multiranged.union.asset.stat_cat_entry.search.stat_cat';
541 my $binds = join($collector, map { 'SELECT id FROM actor.org_unit_full_path(?)' } grep {defined} @$ous);
542 $select =~ s/XXX/$binds/so;
545 $fleshed = 1 if ($self->api_name =~ /fleshed/o);
547 my $sth = asset::stat_cat->db_Main->prepare_cached($select);
548 $sth->execute(map { "$_" } grep {defined} @$ous);
550 for my $sc ( map { asset::stat_cat->construct($_) } $sth->fetchall_hash ) {
551 my $sc_fm = $sc->to_fieldmapper;
553 [ $self->method_lookup( $entry_method )->run($ous, $sc->id) ]
555 $client->respond( $sc_fm );
560 __PACKAGE__->register_method(
561 api_name => 'open-ils.storage.multiranged.intersect.fleshed.asset.stat_cat.all',
564 method => 'multiranged_asset_stat_cat',
566 __PACKAGE__->register_method(
567 api_name => 'open-ils.storage.multiranged.union.fleshed.asset.stat_cat.all',
570 method => 'multiranged_asset_stat_cat',
573 #XXX Fix stored proc calls
574 sub ranged_asset_stat_cat_entry {
580 return undef unless ($ou);
581 my $s_table = asset::stat_cat_entry->table;
583 my $select = <<" SQL";
586 JOIN actor.org_unit_full_path(?) p ON (p.id = s.owner)
591 my $sth = asset::stat_cat->db_Main->prepare_cached($select);
592 $sth->execute($ou,$sc);
594 for my $sce ( map { asset::stat_cat_entry->construct($_) } $sth->fetchall_hash ) {
595 $client->respond( $sce->to_fieldmapper );
600 __PACKAGE__->register_method(
601 api_name => 'open-ils.storage.ranged.asset.stat_cat_entry.search.stat_cat',
604 method => 'ranged_asset_stat_cat_entry',
607 #XXX Fix stored proc calls
608 sub multiranged_asset_stat_cat_entry {
614 return undef unless (defined($ous) and @$ous);
615 my $s_table = asset::stat_cat_entry->table;
617 my $collector = ' INTERSECT ';
618 $collector = ' UNION ' if ($self->api_name =~ /union/o);
620 my $select = <<" SQL";
623 WHERE s.owner IN ( XXX ) and s.stat_cat = ?
627 my $binds = join($collector, map { 'SELECT id FROM actor.org_unit_full_path(?)' } grep {defined} @$ous);
628 $select =~ s/XXX/$binds/so;
630 my $sth = asset::stat_cat->db_Main->prepare_cached($select);
631 $sth->execute(map {"$_"} @$ous,$sc);
633 for my $sce ( map { asset::stat_cat_entry->construct($_) } $sth->fetchall_hash ) {
634 $client->respond( $sce->to_fieldmapper );
639 __PACKAGE__->register_method(
640 api_name => 'open-ils.storage.multiranged.intersect.asset.stat_cat_entry.search.stat_cat',
643 method => 'multiranged_asset_stat_cat_entry',
645 __PACKAGE__->register_method(
646 api_name => 'open-ils.storage.multiranged.union.asset.stat_cat_entry.search.stat_cat',
649 method => 'multiranged_asset_stat_cat_entry',
658 my $depth = shift || 0;
663 ->selectcol_arrayref(
664 'SELECT id FROM actor.org_unit_descendants(?,?)',
670 return undef unless ($ou_list and @$ou_list);
672 $cn = asset::call_number->retrieve( $cn );
673 return undef unless ($cn);
675 my $call_number = $cn->to_fieldmapper;
676 $call_number->copies([]);
678 $call_number->record( $cn->record->to_fieldmapper );
679 $call_number->record->fixed_fields( $cn->record->record_descriptor->next->to_fieldmapper );
681 for my $cp ( $cn->copies(circ_lib => $ou_list) ) {
682 my $copy = $cp->to_fieldmapper;
683 $copy->status( $cp->status->to_fieldmapper );
684 $copy->location( $cp->status->to_fieldmapper );
686 push @{ $call_number->copies }, $copy;
691 __PACKAGE__->register_method(
692 api_name => 'open-ils.storage.asset.call_number.ranged_tree',
693 method => 'cn_ranged_tree',