From ca2139695aef0d1fa0951fe5333faec1ddb5335a Mon Sep 17 00:00:00 2001 From: dbwells Date: Mon, 18 Oct 2010 15:06:21 +0000 Subject: [PATCH] Unify Serial.pm changes (trunk/branch) This mainly involves: Barcode support in unitize_items Distribution tree methods Basic Stream wrapper methods git-svn-id: svn://svn.open-ils.org/ILS/branches/serials-integration@18373 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- .../src/perlmods/OpenILS/Application/Serial.pm | 228 ++++++++++++++++++++- .../staff_client/chrome/content/main/constants.js | 4 + 2 files changed, 223 insertions(+), 9 deletions(-) diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Serial.pm b/Open-ILS/src/perlmods/OpenILS/Application/Serial.pm index f6b53cb7ee..47d4c02899 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Serial.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Serial.pm @@ -668,7 +668,7 @@ sub make_predictions { my $editor = OpenILS::Utils::CStoreEditor->new(); my $ssub_id = $args->{ssub_id}; - my $all_dists = $args->{all_dists}; + my $all_dists = $args->{all_dists}; #TODO: this option supports test-level code, will be removed (i.e. always 'true') my $mfhd = MFHD->new(MARC::Record->new()); my $ssub = $editor->retrieve_serial_subscription([$ssub_id]); @@ -893,17 +893,47 @@ __PACKAGE__->register_method( name => 'items', desc => 'array of serial items', type => 'array' + }, + { + name => 'barcodes', + desc => 'hash of item_ids => barcodes', + type => 'hash' } ], 'return' => { - desc => 'Returns number of received items', - type => 'int' + desc => 'Returns number of received items (num_items) and new unit ID, if applicable (new_unit_id)', + type => 'hashref' + } + } +); + +__PACKAGE__->register_method( + method => 'unitize_items', + api_name => 'open-ils.serial.bind_items', + api_level => 1, + argc => 1, + signature => { + desc => 'Marks an item as bound, updates the shelving unit (creating a new shelving unit if needed)', + 'params' => [ { + name => 'items', + desc => 'array of serial items', + type => 'array' + }, + { + name => 'barcodes', + desc => 'hash of item_ids => barcodes', + type => 'hash' + } + ], + 'return' => { + desc => 'Returns number of bound items (num_items) and new unit ID, if applicable (new_unit_id)', + type => 'hashref' } } ); sub unitize_items { - my ($self, $conn, $auth, $items) = @_; + my ($self, $conn, $auth, $items, $barcodes) = @_; my( $reqr, $evt ) = $U->checkses($auth); return $evt if $evt; @@ -959,7 +989,7 @@ sub unitize_items { if ($unit_id == -1 or (!$new_unit_id and $unit_id == -2)) { # create unit per item my $unit; my $sdists = $editor->search_serial_distribution([{"+sstr" => {"id" => $stream_id}}, { "join" => {"sstr" => {}} }]); - $unit = _build_unit($editor, $sdists->[0], $mode); + $unit = _build_unit($editor, $sdists->[0], $mode, 0, $barcodes->{$item->id}); my $evt = _create_sunit($editor, $unit); return $evt if $evt; if ($unit_id == -2) { @@ -995,7 +1025,7 @@ sub unitize_items { foreach my $unit_id (keys %found_unit_ids) { # get all the needed issuances for unit - my $issuances = $editor->search_serial_issuance([ {"+sitem" => {"unit" => $unit_id, "status" => "Received"}}, {"join" => {"sitem" => {}}, "order_by" => {"siss" => "date_published"}} ]); + my $issuances = $editor->search_serial_issuance([ {"+sitem" => {"unit" => $unit_id, "status" => ["Received", "Bindery"]}}, {"join" => {"sitem" => {}}, "order_by" => {"siss" => "date_published"}} ]); #TODO: evt on search failure my ($mfhd, $formatted_parts) = _summarize_contents($editor, $issuances); @@ -1038,7 +1068,11 @@ sub unitize_items { return $evt if $evt; } - # TODO: cleanup 'dead' units (units which are now emptied of their items) + # cleanup 'dead' units (units which are now emptied of their items) + my $dead_units = $editor->search_serial_unit([{'+sitem' => {'id' => undef}, 'deleted' => 'f'}, {'join' => {'sitem' => {'type' => 'left'}}}]); + foreach my $unit (@$dead_units) { + _delete_sunit($editor, undef, $unit); + } if ($mode eq 'receive') { # the summary holdings do not change when binding # deal with stream level summaries @@ -1090,7 +1124,7 @@ sub unitize_items { } $editor->commit; - return {'num_items_received' => scalar @$items, 'new_unit_id' => $new_unit_id}; + return {'num_items' => scalar @$items, 'new_unit_id' => $new_unit_id}; } sub _find_or_create_call_number { @@ -1368,6 +1402,7 @@ sub _build_unit { my $sdist = shift; my $mode = shift; my $skip_call_number = shift; + my $barcode = shift; my $attr = $mode . '_unit_template'; my $template = $editor->retrieve_asset_copy_template($sdist->$attr) or @@ -1395,7 +1430,11 @@ sub _build_unit { $unit->call_number($cn); } - $unit->barcode('AUTO'); + if ($barcode) { + $unit->barcode($barcode); + } else { + $unit->barcode('AUTO'); + } $unit->sort_key(''); $unit->summary_contents(''); $unit->detailed_contents(''); @@ -1998,6 +2037,62 @@ sub fleshed_serial_distribution_retrieve_batch { }); } +__PACKAGE__->register_method( + method => "retrieve_dist_tree", + authoritative => 1, + api_name => "open-ils.serial.distribution_tree.retrieve" +); + +__PACKAGE__->register_method( + method => "retrieve_dist_tree", + api_name => "open-ils.serial.distribution_tree.global.retrieve" +); + +sub retrieve_dist_tree { + my( $self, $client, $user_session, $docid, @org_ids ) = @_; + + if(ref($org_ids[0])) { @org_ids = @{$org_ids[0]}; } + + $docid = "$docid"; + + # TODO: permission support + if(!@org_ids and $user_session) { + my $user_obj = + OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error + @org_ids = ($user_obj->home_ou); + } + + my $e = new_editor(); + + if( $self->api_name =~ /global/ ) { + return $e->search_serial_distribution([{'+ssub' => { record_entry => $docid }}, + { flesh => 1, + flesh_fields => {sdist => [ qw/ holding_lib receive_call_number receive_unit_template bind_call_number bind_unit_template streams basic_summary supplement_summary index_summary / ]}, + order_by => {'sdist' => 'id'}, + 'join' => {'ssub' => {}} + } + ]); # TODO: filter for !deleted? + + } else { + my @all_dists; + for my $orgid (@org_ids) { + my $dists = $e->search_serial_distribution([{'+ssub' => { record_entry => $docid }, holding_lib => $orgid}, + { flesh => 1, + flesh_fields => {sdist => [ qw/ holding_lib receive_call_number receive_unit_template bind_call_number bind_unit_template streams basic_summary supplement_summary index_summary / ]}, + order_by => {'sdist' => 'id'}, + 'join' => {'ssub' => {}} + } + ]); # TODO: filter for !deleted? + push( @all_dists, @$dists ) if $dists; + } + + return \@all_dists; + } + + return undef; +} + + ########################################################################## # caption and pattern methods # @@ -2109,6 +2204,121 @@ sub serial_caption_and_pattern_retrieve_batch { ); } +########################################################################## +# stream methods +# +__PACKAGE__->register_method( + method => 'sstr_alter', + api_name => 'open-ils.serial.stream.batch.update', + api_level => 1, + argc => 2, + signature => { + desc => 'Receives an array of one or more streams and updates the database as needed', + 'params' => [ { + name => 'authtoken', + desc => 'Authtoken for current user session', + type => 'string' + }, + { + name => 'sstrs', + desc => 'Array of streams', + type => 'array' + } + + ], + 'return' => { + desc => 'Returns 1 if successful, event if failed', + type => 'mixed' + } + } +); + +sub sstr_alter { + my( $self, $conn, $auth, $sstrs ) = @_; + return 1 unless ref $sstrs; + my( $reqr, $evt ) = $U->checkses($auth); + return $evt if $evt; + my $editor = new_editor(requestor => $reqr, xact => 1); + my $override = $self->api_name =~ /override/; + +# TODO: permission check +# return $editor->event unless +# $editor->allowed('UPDATE_COPY', $class->copy_perm_org($vol, $copy)); + + for my $sstr (@$sstrs) { + my $sstrid = $sstr->id; + + if( $sstr->isdeleted ) { + $evt = _delete_sstr( $editor, $override, $sstr); + } elsif( $sstr->isnew ) { + $evt = _create_sstr( $editor, $sstr ); + } else { + $evt = _update_sstr( $editor, $override, $sstr ); + } + } + + if( $evt ) { + $logger->info("stream-alter failed with event: ".OpenSRF::Utils::JSON->perl2JSON($evt)); + $editor->rollback; + return $evt; + } + $logger->debug("stream-alter: done updating stream batch"); + $editor->commit; + $logger->info("stream-alter successfully updated ".scalar(@$sstrs)." streams"); + return 1; +} + +sub _delete_sstr { + my ($editor, $override, $sstr) = @_; + $logger->info("stream-alter: delete stream ".OpenSRF::Utils::JSON->perl2JSON($sstr)); + my $sitems = $editor->search_serial_item( + { stream => $sstr->id }, { limit => 1 } ); #TODO: 'deleted' support? + return OpenILS::Event->new( + 'SERIAL_STREAM_HAS_ITEMS', payload => $sstr->id ) if (@$sitems); + + return $editor->event unless $editor->delete_serial_stream($sstr); + return 0; +} + +sub _create_sstr { + my ($editor, $sstr) = @_; + + $logger->info("stream-alter: new stream ".OpenSRF::Utils::JSON->perl2JSON($sstr)); + return $editor->event unless $editor->create_serial_stream($sstr); + return 0; +} + +sub _update_sstr { + my ($editor, $override, $sstr) = @_; + + $logger->info("stream-alter: retrieving stream ".$sstr->id); + my $orig_sstr = $editor->retrieve_serial_stream($sstr->id); + + $logger->info("stream-alter: original stream ".OpenSRF::Utils::JSON->perl2JSON($orig_sstr)); + $logger->info("stream-alter: updated stream ".OpenSRF::Utils::JSON->perl2JSON($sstr)); + return $editor->event unless $editor->update_serial_stream($sstr); + return 0; +} + +__PACKAGE__->register_method( + method => "serial_stream_retrieve_batch", + authoritative => 1, + api_name => "open-ils.serial.stream.batch.retrieve" +); + +sub serial_stream_retrieve_batch { + my( $self, $client, $ids ) = @_; + $logger->info("Fetching streams @$ids"); + return $U->cstorereq( + "open-ils.cstore.direct.serial.stream.search.atomic", + { id => $ids } + ); +} + + +########################################################################## +# other methods +# __PACKAGE__->register_method( "method" => "bre_by_identifier", "api_name" => "open-ils.serial.biblio.record_entry.by_identifier", diff --git a/Open-ILS/xul/staff_client/chrome/content/main/constants.js b/Open-ILS/xul/staff_client/chrome/content/main/constants.js index e95db3d3c6..e216b54deb 100644 --- a/Open-ILS/xul/staff_client/chrome/content/main/constants.js +++ b/Open-ILS/xul/staff_client/chrome/content/main/constants.js @@ -286,6 +286,8 @@ var api = { 'FM_SDIST_FLESHED_BATCH_RETRIEVE.authoritative' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.distribution.fleshed.batch.retrieve.authoritative', 'secure' : false }, 'FM_SDIST_ID_LIST' : { 'app' : 'open-ils.pcrud', 'method' : 'open-ils.pcrud.id_list.sdist'}, 'FM_SDIST_RETRIEVE' : { 'app' : 'open-ils.pcrud', 'method' : 'open-ils.pcrud.retrieve.sdist'}, + 'FM_SDIST_TREE_LIST_RETRIEVE_VIA_RECORD_ID_AND_ORG_IDS' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.distribution_tree.retrieve', 'secure' : false }, + 'FM_SDIST_TREE_LIST_RETRIEVE_VIA_RECORD_ID_AND_ORG_IDS.authoritative' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.distribution_tree.retrieve.authoritative', 'secure' : false }, 'FM_SDIST_SEARCH' : { 'app' : 'open-ils.pcrud', 'method' : 'open-ils.pcrud.search.sdist'}, 'FM_SDISTN_CREATE' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.distribution_note.create' }, 'FM_SDISTN_DELETE' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.distribution_note.delete', 'secure' : false }, @@ -302,6 +304,8 @@ var api = { 'FM_SITEM_SEARCH' : { 'app' : 'open-ils.pcrud', 'method' : 'open-ils.pcrud.search.sitem'}, 'FM_SRE_RETRIEVE' : { 'app' : 'open-ils.pcrud', 'method' : 'open-ils.pcrud.retrieve.sre'}, 'FM_SRE_SEARCH' : { 'app' : 'open-ils.pcrud', 'method' : 'open-ils.pcrud.search.sre'}, + 'FM_SSTR_BATCH_RETRIEVE' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.stream.batch.retrieve', 'secure' : false }, + 'FM_SSTR_BATCH_RETRIEVE.authoritative' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.stream.batch.retrieve', 'secure' : false }, 'FM_SSUB_AOU_IDS_RETRIEVE_VIA_RECORD_ID' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.subscription.retrieve_orgs_by_title', 'secure' : false }, 'FM_SSUB_AOU_IDS_RETRIEVE_VIA_RECORD_ID.authoritative' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.subscription.retrieve_orgs_by_title.authoritative', 'secure' : false }, 'FM_SSUB_FLESHED_BATCH_RETRIEVE' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.subscription.fleshed.batch.retrieve', 'secure' : false }, -- 2.11.0