From 247f7ba645e303e557f036a7b0d002d53b7d41e9 Mon Sep 17 00:00:00 2001 From: senator Date: Wed, 10 Nov 2010 17:54:34 +0000 Subject: [PATCH] Merge serials-integration branch, incorporating new work from Dan Wells. Specifically, this contains changesets 18670, 18669, 18379, and 18373. git-svn-id: svn://svn.open-ils.org/ILS/trunk@18685 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- .../perlmods/OpenILS/Application/Serial.pm | 415 ++++- Open-ILS/web/opac/locale/en-US/lang.dtd | 10 + .../chrome/content/main/constants.js | 12 + .../server/locale/en-US/serial.properties | 18 + .../staff_client/server/serial/editor_base.js | 21 +- .../server/serial/manage_dists.js | 1337 +++++++++++++++++ .../server/serial/manage_dists.xul | 104 ++ .../staff_client/server/serial/manage_subs.js | 2 +- .../server/serial/sbsum_editor.js | 121 ++ .../server/serial/sbsum_editor.xul | 33 + .../server/serial/sdist2_editor.xul | 44 + .../server/serial/sdist_editor.js | 14 +- .../server/serial/sisum_editor.js | 121 ++ .../server/serial/sisum_editor.xul | 33 + .../server/serial/sssum_editor.js | 121 ++ .../server/serial/sssum_editor.xul | 33 + .../staff_client/server/serial/sstr_editor.js | 116 ++ .../server/serial/sstr_editor.xul | 33 + 18 files changed, 2566 insertions(+), 22 deletions(-) create mode 100644 Open-ILS/xul/staff_client/server/serial/manage_dists.js create mode 100644 Open-ILS/xul/staff_client/server/serial/manage_dists.xul create mode 100644 Open-ILS/xul/staff_client/server/serial/sbsum_editor.js create mode 100644 Open-ILS/xul/staff_client/server/serial/sbsum_editor.xul create mode 100644 Open-ILS/xul/staff_client/server/serial/sdist2_editor.xul create mode 100644 Open-ILS/xul/staff_client/server/serial/sisum_editor.js create mode 100644 Open-ILS/xul/staff_client/server/serial/sisum_editor.xul create mode 100644 Open-ILS/xul/staff_client/server/serial/sssum_editor.js create mode 100644 Open-ILS/xul/staff_client/server/serial/sssum_editor.xul create mode 100644 Open-ILS/xul/staff_client/server/serial/sstr_editor.js create mode 100644 Open-ILS/xul/staff_client/server/serial/sstr_editor.xul diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Serial.pm b/Open-ILS/src/perlmods/OpenILS/Application/Serial.pm index dcdb11d770..adcbe4862f 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 (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 received items', - type => 'int' + 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,8 @@ 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}); + # TODO: catch events from _build_unit my $evt = _create_sunit($editor, $unit); return $evt if $evt; if ($unit_id == -2) { @@ -995,7 +1026,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 +1069,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 +1125,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 { @@ -1438,6 +1473,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 @@ -1465,7 +1501,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(''); @@ -2068,6 +2108,81 @@ 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; +} + + +__PACKAGE__->register_method( + method => "distribution_orgs_for_title", + authoritative => 1, + api_name => "open-ils.serial.distribution.retrieve_orgs_by_title" +); + +sub distribution_orgs_for_title { + my( $self, $client, $record_id ) = @_; + + my $dists = $U->cstorereq( + "open-ils.cstore.direct.serial.distribution.search.atomic", + { '+ssub' => { record_entry => $record_id } }, + { 'join' => {'ssub' => {}} }); # TODO: filter on !deleted? + + my $orgs = { map {$_->holding_lib => 1 } @$dists }; + return [ keys %$orgs ]; +} + + ########################################################################## # caption and pattern methods # @@ -2179,6 +2294,288 @@ 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 } + ); +} + + +########################################################################## +# summary methods +# +__PACKAGE__->register_method( + method => 'sum_alter', + api_name => 'open-ils.serial.basic_summary.batch.update', + api_level => 1, + argc => 2, + signature => { + desc => 'Receives an array of one or more summaries and updates the database as needed', + 'params' => [ { + name => 'authtoken', + desc => 'Authtoken for current user session', + type => 'string' + }, + { + name => 'sbsums', + desc => 'Array of basic summaries', + type => 'array' + } + + ], + 'return' => { + desc => 'Returns 1 if successful, event if failed', + type => 'mixed' + } + } +); + +__PACKAGE__->register_method( + method => 'sum_alter', + api_name => 'open-ils.serial.supplement_summary.batch.update', + api_level => 1, + argc => 2, + signature => { + desc => 'Receives an array of one or more summaries and updates the database as needed', + 'params' => [ { + name => 'authtoken', + desc => 'Authtoken for current user session', + type => 'string' + }, + { + name => 'sbsums', + desc => 'Array of supplement summaries', + type => 'array' + } + + ], + 'return' => { + desc => 'Returns 1 if successful, event if failed', + type => 'mixed' + } + } +); + +__PACKAGE__->register_method( + method => 'sum_alter', + api_name => 'open-ils.serial.index_summary.batch.update', + api_level => 1, + argc => 2, + signature => { + desc => 'Receives an array of one or more summaries and updates the database as needed', + 'params' => [ { + name => 'authtoken', + desc => 'Authtoken for current user session', + type => 'string' + }, + { + name => 'sbsums', + desc => 'Array of index summaries', + type => 'array' + } + + ], + 'return' => { + desc => 'Returns 1 if successful, event if failed', + type => 'mixed' + } + } +); + +sub sum_alter { + my( $self, $conn, $auth, $sums ) = @_; + return 1 unless ref $sums; + + $self->api_name =~ /serial\.(\w*)_summary/; + my $type = $1; + + 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 $sum (@$sums) { + my $sumid = $sum->id; + + # XXX: (for now, at least) summaries should be created/deleted by the distribution functions + if( $sum->isdeleted ) { + $evt = OpenILS::Event->new('SERIAL_SUMMARIES_NOT_INDEPENDENT'); + } elsif( $sum->isnew ) { + $evt = OpenILS::Event->new('SERIAL_SUMMARIES_NOT_INDEPENDENT'); + } else { + $evt = _update_sum( $editor, $override, $sum, $type ); + } + } + + if( $evt ) { + $logger->info("${type}_summary-alter failed with event: ".OpenSRF::Utils::JSON->perl2JSON($evt)); + $editor->rollback; + return $evt; + } + $logger->debug("${type}_summary-alter: done updating ${type}_summary batch"); + $editor->commit; + $logger->info("${type}_summary-alter successfully updated ".scalar(@$sums)." ${type}_summaries"); + return 1; +} + +sub _update_sum { + my ($editor, $override, $sum, $type) = @_; + + $logger->info("${type}_summary-alter: retrieving ${type}_summary ".$sum->id); + my $retrieve_method = "retrieve_serial_${type}_summary"; + my $orig_sum = $editor->$retrieve_method($sum->id); + + $logger->info("${type}_summary-alter: original ${type}_summary ".OpenSRF::Utils::JSON->perl2JSON($orig_sum)); + $logger->info("${type}_summary-alter: updated ${type}_summary ".OpenSRF::Utils::JSON->perl2JSON($sum)); + my $update_method = "update_serial_${type}_summary"; + return $editor->event unless $editor->$update_method($sum); + return 0; +} + +__PACKAGE__->register_method( + method => "serial_summary_retrieve_batch", + authoritative => 1, + api_name => "open-ils.serial.basic_summary.batch.retrieve" +); + +__PACKAGE__->register_method( + method => "serial_summary_retrieve_batch", + authoritative => 1, + api_name => "open-ils.serial.supplement_summary.batch.retrieve" +); + +__PACKAGE__->register_method( + method => "serial_summary_retrieve_batch", + authoritative => 1, + api_name => "open-ils.serial.index_summary.batch.retrieve" +); + +sub serial_summary_retrieve_batch { + my( $self, $client, $ids ) = @_; + + $self->api_name =~ /serial\.(\w*)_summary/; + my $type = $1; + + $logger->info("Fetching ${type}_summaries @$ids"); + return $U->cstorereq( + "open-ils.cstore.direct.serial.".$type."_summary.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/web/opac/locale/en-US/lang.dtd b/Open-ILS/web/opac/locale/en-US/lang.dtd index a1251429b0..c0e49b5933 100644 --- a/Open-ILS/web/opac/locale/en-US/lang.dtd +++ b/Open-ILS/web/opac/locale/en-US/lang.dtd @@ -1596,6 +1596,12 @@ + + + + + + @@ -1615,6 +1621,10 @@ + + + + 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 459cd6542a..00521de0ca 100644 --- a/Open-ILS/xul/staff_client/chrome/content/main/constants.js +++ b/Open-ILS/xul/staff_client/chrome/content/main/constants.js @@ -281,13 +281,19 @@ var api = { 'MARC_HTML_RETRIEVE' : { 'app' : 'open-ils.search', 'method' : 'open-ils.search.biblio.record.html', 'secure' : false }, 'FM_BLOB_RETRIEVE_VIA_Z3950_SEARCH' : { 'app' : 'open-ils.search', 'method' : 'open-ils.search.z3950.search_class' }, 'FM_BLOB_RETRIEVE_VIA_Z3950_RAW_SEARCH' : { 'app' : 'open-ils.search', 'method' : 'open-ils.search.z3950.search_service' }, + 'FM_SBSUM_BATCH_RETRIEVE' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.basic_summary.batch.retrieve', 'secure' : false }, + 'FM_SBSUM_BATCH_RETRIEVE.authoritative' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.basic_summary.batch.retrieve.authoritative', 'secure' : false }, 'FM_SCAP_BATCH_RETRIEVE' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.caption_and_pattern.batch.retrieve', 'secure' : false }, 'FM_SCAP_BATCH_RETRIEVE.authoritative' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.caption_and_pattern.batch.retrieve', 'secure' : false }, + 'FM_SDIST_AOU_IDS_RETRIEVE_VIA_RECORD_ID' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.distribution.retrieve_orgs_by_title', 'secure' : false }, + 'FM_SDIST_AOU_IDS_RETRIEVE_VIA_RECORD_ID.authoritative' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.distribution.retrieve_orgs_by_title.authoritative', 'secure' : false }, 'FM_SDIST_FLESHED_BATCH_RETRIEVE' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.distribution.fleshed.batch.retrieve', 'secure' : false }, '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_SEARCH' : { 'app' : 'open-ils.pcrud', 'method' : 'open-ils.pcrud.search.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_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 }, 'FM_SDISTN_RETRIEVE_ALL' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.distribution_note.retrieve.all', 'secure' : false }, @@ -296,6 +302,8 @@ var api = { 'FM_SIN_RETRIEVE_ALL' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.item_note.retrieve.all', 'secure' : false }, 'FM_SISS_FLESHED_BATCH_RETRIEVE' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.issuance.fleshed.batch.retrieve', 'secure' : false }, 'FM_SISS_FLESHED_BATCH_RETRIEVE.authoritative' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.issuance.fleshed.batch.retrieve.authoritative', 'secure' : false }, + 'FM_SISUM_BATCH_RETRIEVE' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.index_summary.batch.retrieve', 'secure' : false }, + 'FM_SISUM_BATCH_RETRIEVE.authoritative' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.index_summary.batch.retrieve.authoritative', 'secure' : false }, 'FM_SITEM_FLESHED_BATCH_RETRIEVE' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.item.fleshed.batch.retrieve', 'secure' : false }, 'FM_SITEM_FLESHED_BATCH_RETRIEVE.authoritative' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.item.fleshed.batch.retrieve.authoritative', 'secure' : false }, 'FM_SITEM_ID_LIST' : { 'app' : 'open-ils.pcrud', 'method' : 'open-ils.pcrud.id_list.sitem'}, @@ -303,6 +311,10 @@ 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_SSSUM_BATCH_RETRIEVE' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.supplement_summary.batch.retrieve', 'secure' : false }, + 'FM_SSSUM_BATCH_RETRIEVE.authoritative' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.supplement_summary.batch.retrieve.authoritative', 'secure' : false }, + '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.authoritative', '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 }, diff --git a/Open-ILS/xul/staff_client/server/locale/en-US/serial.properties b/Open-ILS/xul/staff_client/server/locale/en-US/serial.properties index 84b0669f5a..9df704562f 100644 --- a/Open-ILS/xul/staff_client/server/locale/en-US/serial.properties +++ b/Open-ILS/xul/staff_client/server/locale/en-US/serial.properties @@ -1,5 +1,17 @@ staff.serial.editor_base.handle_update.error=serial update error: staff.serial.editor_base.handle_update.success=Save Successful +staff.serial.sbsum_editor.count=1 summary +staff.serial.sbsum_editor.count.plural=%1$s summaries +staff.serial.sbsum_editor.modify=Modify Basic Summary +staff.serial.sbsum_editor.modify.accesskey=M +staff.serial.sisum_editor.count=1 summary +staff.serial.sisum_editor.count.plural=%1$s summaries +staff.serial.sisum_editor.modify=Modify Index Summary +staff.serial.sisum_editor.modify.accesskey=M +staff.serial.sssum_editor.count=1 summary +staff.serial.sssum_editor.count.plural=%1$s summaries +staff.serial.sssum_editor.modify=Modify Supplement Summary +staff.serial.sssum_editor.modify.accesskey=M staff.serial.scap_editor.count=1 caption and pattern staff.serial.scap_editor.count.plural=%1$s caption and patterns staff.serial.scap_editor.create=Create Caption and Pattern(s) @@ -28,6 +40,12 @@ staff.serial.sitem_editor.create.accesskey=C staff.serial.sitem_editor.modify=Modify Item(s) staff.serial.sitem_editor.modify.accesskey=M staff.serial.sitem_editor.notes=Item Notes +staff.serial.sstr_editor.count=1 stream +staff.serial.sstr_editor.count.plural=%1$s streams +staff.serial.sstr_editor.create=Create Stream(s) +staff.serial.sstr_editor.create.accesskey=C +staff.serial.sstr_editor.modify=Modify Stream(s) +staff.serial.sstr_editor.modify.accesskey=M staff.serial.ssub_editor.count=1 subscription staff.serial.ssub_editor.count.plural=%1$s subscriptions staff.serial.ssub_editor.create=Create Subscription(s) diff --git a/Open-ILS/xul/staff_client/server/serial/editor_base.js b/Open-ILS/xul/staff_client/server/serial/editor_base.js index 4caf526462..13f17361a4 100644 --- a/Open-ILS/xul/staff_client/server/serial/editor_base.js +++ b/Open-ILS/xul/staff_client/server/serial/editor_base.js @@ -45,6 +45,11 @@ serial.editor_base = { if (!retrieve_params) { retrieve_params = []; } + if (params.xul_id_prefix) { + obj.xul_id_prefix = params.xul_id_prefix; + } else { + obj.xul_id_prefix = fm_type; + } /******************************************************************************************************/ /* Get the fm_type ids from various sources and flesh them */ @@ -136,7 +141,7 @@ serial.editor_base = { } if (obj.do_edit) { - $(fm_type + '_save').setAttribute('hidden','false'); + $(obj.xul_id_prefix + '_save').setAttribute('hidden','false'); } else { $('top_nav').setAttribute('hidden','true'); } @@ -147,14 +152,14 @@ serial.editor_base = { if (obj[fm_type_plural].length > 0 && obj[fm_type_plural][0].isnew()) { obj.mode = 'create'; - if (obj.can_have_notes) $(fm_type + '_notes').setAttribute('hidden','true'); - $(fm_type + '_save').setAttribute('label', $('serialStrings').getString('staff.serial.' + fm_type + '_editor.create')); - $(fm_type + '_save').setAttribute('accesskey', $('serialStrings').getString('staff.serial.' + fm_type + '_editor.create.accesskey')); + if (obj.can_have_notes) $(obj.xul_id_prefix + '_notes').setAttribute('hidden','true'); + $(obj.xul_id_prefix + '_save').setAttribute('label', $('serialStrings').getString('staff.serial.' + fm_type + '_editor.create')); + $(obj.xul_id_prefix + '_save').setAttribute('accesskey', $('serialStrings').getString('staff.serial.' + fm_type + '_editor.create.accesskey')); } else if (obj.mode == 'create') { // switching from create to modify obj.mode = 'modify'; - if (obj.can_have_notes) $(fm_type + '_notes').setAttribute('hidden','false'); - $(fm_type + '_save').setAttribute('label', $('serialStrings').getString('staff.serial.' + fm_type + '_editor.modify')); - $(fm_type + '_save').setAttribute('accesskey', $('serialStrings').getString('staff.serial.' + fm_type + '_editor.modify.accesskey')); + if (obj.can_have_notes) $(obj.xul_id_prefix + '_notes').setAttribute('hidden','false'); + $(obj.xul_id_prefix + '_save').setAttribute('label', $('serialStrings').getString('staff.serial.' + fm_type + '_editor.modify')); + $(obj.xul_id_prefix + '_save').setAttribute('accesskey', $('serialStrings').getString('staff.serial.' + fm_type + '_editor.modify.accesskey')); } /*else { obj.panes_and_field_names.left_pane = @@ -171,7 +176,7 @@ serial.editor_base = { }*/ if (obj[fm_type_plural].length != 1) { - document.getElementById(fm_type + '_notes').setAttribute('hidden','true'); + if (obj.can_have_notes) $(obj.xul_id_prefix + '_notes').setAttribute('hidden','true'); } // clear change markers diff --git a/Open-ILS/xul/staff_client/server/serial/manage_dists.js b/Open-ILS/xul/staff_client/server/serial/manage_dists.js new file mode 100644 index 0000000000..2adcd4a72e --- /dev/null +++ b/Open-ILS/xul/staff_client/server/serial/manage_dists.js @@ -0,0 +1,1337 @@ +dump('entering serial/manage_dists.js\n'); +// vim:noet:sw=4:ts=4: + +if (typeof serial == 'undefined') serial = {}; +serial.manage_dists = function (params) { + try { + netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); + JSAN.use('util.error'); this.error = new util.error(); + } catch(E) { + dump('serial/manage_dists: ' + E + '\n'); + } +}; + +serial.manage_dists.prototype = { + + 'map_tree' : {}, + 'map_sdist' : {}, + //'map_sstr' : {}, + 'sel_list' : [], + 'funcs' : [], + 'editor_indexes' : { 'sdist' : 1, 'sstr' : 2, 'sbsum' : 3, 'sssum' : 4, 'sisum' : 5 }, + + 'ids_from_sel_list' : function(type) { + var obj = this; + JSAN.use('util.functional'); + + var list = util.functional.map_list( + util.functional.filter_list( + obj.sel_list, + function (o) { + return o.split(/_/)[0] == type; + } + ), + function (o) { + return o.split(/_/)[1]; + } + ); + + return list; + }, + + 'editor_init' : function(type, mode, params) { + var obj = this; + try { + $('serial_manage_dists_editor_deck').selectedIndex = obj.editor_indexes[type]; + var editor_type = type + '_editor'; + if (typeof obj[editor_type] == 'undefined') { + JSAN.use('serial.' + editor_type); + obj[editor_type] = new serial[editor_type](); + } + + params.do_edit = true; + params.handle_update = true; + if (mode == 'add') { + params.trigger_refresh = true; + params.refresh_command = function () {obj.refresh_list();}; + } + obj[editor_type].init(params); + } catch(E) { + obj.error.standard_unexpected_error_alert('editor_init() error',E); + } + }, + + 'do_delete' : function(type, method, overridable_events) { + var obj = this; + try { + JSAN.use('util.functional'); + + var list = util.functional.filter_list( + obj.sel_list, + function (o) { + return o.split(/_/)[0] == type; + } + ); + + list = util.functional.map_list( + list, + function (o) { + return JSON2js( js2JSON( obj['map_' + type][ type + '_' + o.split(/_/)[1] ] ) ); + } + ); + + //TODO: proper messages + var delete_msg; + if (list.length != 1) { + delete_msg = document.getElementById('serialStrings').getFormattedString('staff.serial.manage_subs.delete_' + type + '.confirm.plural', [list.length]); + } else { + delete_msg = document.getElementById('serialStrings').getString('staff.serial.manage_subs.delete_' + type + '.confirm'); + } + var r = obj.error.yns_alert( + delete_msg, + document.getElementById('serialStrings').getString('staff.serial.manage_subs.delete_' + type + '.title'), + document.getElementById('catStrings').getString('staff.cat.copy_browser.delete_items.delete'), + document.getElementById('catStrings').getString('staff.cat.copy_browser.delete_items.cancel'), + null, + document.getElementById('commonStrings').getString('common.confirm') + ); + + if (r == 0) { + for (var i = 0; i < list.length; i++) { + list[i].isdeleted('1'); + } + var robj = obj.network.request( + 'open-ils.serial', + method, + [ ses(), list, true ], + null, + { + 'title' : document.getElementById('serialStrings').getString('staff.serial.manage_subs.delete_' + type + '.override'), + 'overridable_events' : overridable_events + } + ); + if (robj == null) throw(robj); + if (typeof robj.ilsevent != 'undefined') { + if (robj.ilsevent != 0) { + var overridable = false; + for (i = 0; i < overridable_events.length; i++) { + if (overridable_events[i] == robj.ilsevent) { + overridable = true; + break; + } + } + if (!overridable) throw(robj); + } + } + obj.refresh_list(); + } + } catch(E) { + obj.error.standard_unexpected_error_alert(document.getElementById('serialStrings').getString('staff.serial.manage_subs.delete.error'),E); + obj.refresh_list(); + } + }, + + 'init' : function( params ) { + + try { + netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); + var obj = this; + + obj.docid = params.docid; + + JSAN.use('util.network'); obj.network = new util.network(); + JSAN.use('OpenILS.data'); obj.data = new OpenILS.data(); obj.data.init({'via':'stash'}); + JSAN.use('util.controller'); obj.controller = new util.controller(); + obj.controller.init( + { + control_map : { + 'save_columns' : [ [ 'command' ], function() { obj.list.save_columns(); } ], + 'sel_clip' : [ + ['command'], + function() { obj.list.clipboard(); } + ], + 'cmd_broken' : [ + ['command'], + function() { + alert(document.getElementById('commonStrings').getString('common.unimplemented')); + } + ], + 'cmd_show_my_libs' : [ + ['command'], + function() { + obj.show_my_libs(); + } + ], + 'cmd_clear' : [ + ['command'], + function() { + obj.map_tree = {}; + obj.list.clear(); + } + ], + 'cmd_add_siss' : [ + ['command'], + function() { + try { + var list = obj.ids_from_sel_list('sdist'); + if (list.length == 0) list = obj.ids_from_sel_list('siss-group'); + if (list.length == 0) return; + + /*TODO: permission check? + //populate 'list' with owning_libs of subs, TODO + var edit = 0; + try { + edit = obj.network.request( + api.PERM_MULTI_ORG_CHECK.app, + api.PERM_MULTI_ORG_CHECK.method, + [ + ses(), + obj.data.list.au[0].id(), + list, + [ 'CREATE_COPY' ] + ] + ).length == 0 ? 1 : 0; + } catch(E) { + obj.error.sdump('D_ERROR','batch permission check: ' + E); + } + + if (edit==0) return; // no read-only view for this interface */ + var new_siss = new siss(); + new_siss.subscription(list[0]);//TODO: add multiple at once support? + new_siss.isnew(1); + var params = {}; + params.sisses = [new_siss]; + obj.editor_init('siss', 'add', params); + } catch(E) { + obj.error.standard_unexpected_error_alert(document.getElementById('serialStrings').getString('staff.serial.manage_subs.add.error'),E); + } + } + ], + 'cmd_add_sstr' : [ + ['command'], + function() { + try { + var list = obj.ids_from_sel_list('sdist'); + if (list.length == 0) list = obj.ids_from_sel_list('sstr-group'); + if (list.length == 0) return; + + /*TODO: permission check? + //populate 'list' with owning_libs of subs, TODO + var edit = 0; + try { + edit = obj.network.request( + api.PERM_MULTI_ORG_CHECK.app, + api.PERM_MULTI_ORG_CHECK.method, + [ + ses(), + obj.data.list.au[0].id(), + list, + [ 'CREATE_COPY' ] + ] + ).length == 0 ? 1 : 0; + } catch(E) { + obj.error.sdump('D_ERROR','batch permission check: ' + E); + } + + if (edit==0) return; // no read-only view for this interface */ + var new_sstr = new sstr(); + new_sstr.subscription(list[0]);//TODO: add multiple at once support? + new_sstr.holding_lib(obj.map_sdist['sdist_' + list[0]].owning_lib());//default to sub owning lib + new_sstr.label('Default'); + new_sstr.isnew(1); + var params = {}; + params.sstrs = [new_sstr]; + obj.editor_init('sstr', 'add', params); + } catch(E) { + obj.error.standard_unexpected_error_alert(document.getElementById('serialStrings').getString('staff.serial.manage_subs.add.error'),E); + } + } + ], + 'cmd_delete_sstr' : [ + ['command'], + function() { + var overridable_events = [ //TODO: proper overrides + ]; + obj.do_delete('sstr', 'open-ils.serial.distribution.fleshed.batch.update', overridable_events); + } + ], + 'cmd_delete_siss' : [ + ['command'], + function() { + var overridable_events = [ //TODO: proper overrides + ]; + obj.do_delete('siss', 'open-ils.serial.issuance.fleshed.batch.update', overridable_events); + } + ], + 'cmd_delete_sdist' : [ + ['command'], + function() { + var overridable_events = [ + 11000 // SERIAL_SUBSCRIPTION_NOT_EMPTY + ]; + obj.do_delete('sdist', 'open-ils.serial.subscription.fleshed.batch.update', overridable_events); + } + ], + 'cmd_mark_library' : [ + ['command'], + function() { + try { + var list = obj.ids_from_sel_list('aou'); + if (list.length == 1) { + obj.data.marked_library = { 'lib' : list[0], 'docid' : obj.docid }; + obj.data.stash('marked_library'); + alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.mark_library.alert')); + } else { + obj.error.yns_alert( + document.getElementById('catStrings').getString('staff.cat.copy_browser.mark_library.prompt'), + document.getElementById('catStrings').getString('staff.cat.copy_browser.mark_library.title'), + document.getElementById('commonStrings').getString('common.ok'), + null, + null, + document.getElementById('commonStrings').getString('common.confirm') + ); + } + } catch(E) { + obj.error.standard_unexpected_error_alert('manage_dists.js -> mark library',E); + } + } + ], + + 'cmd_mark_distribution' : [ + ['command'], + function() { + try { + var list = obj.ids_from_sel_list('sdist'); + if (list.length == 1) { + obj.data.marked_distribution = list[0]; + obj.data.stash('marked_distribution'); + alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.mark_volume.alert')); + } else { + obj.error.yns_alert( + document.getElementById('catStrings').getString('staff.cat.copy_browser.mark_volume.prompt'), + document.getElementById('catStrings').getString('staff.cat.copy_browser.mark_volume.title'), + document.getElementById('commonStrings').getString('common.ok'), + null, + null, + document.getElementById('commonStrings').getString('common.confirm') + ); + } + } catch(E) { + obj.error.standard_unexpected_error_alert('manage_dists.js -> mark distribution',E); + } + } + ], + 'cmd_add_distributions' : [ + ['command'], + function() { + try { + var list = obj.ids_from_sel_list('aou'); + if (list.length == 0) return; + //TODO: permission check? + /*var edit = 0; + try { + edit = obj.network.request( + api.PERM_MULTI_ORG_CHECK.app, + api.PERM_MULTI_ORG_CHECK.method, + [ + ses(), + obj.data.list.au[0].id(), + list, + [ 'CREATE_VOLUME', 'CREATE_COPY' ] + ] + ).length == 0 ? 1 : 0; + } catch(E) { + obj.error.sdump('D_ERROR','batch permission check: ' + E); + } + + if (edit==0) { + alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.add_volume.permission_error')); + return; // no read-only view for this interface + } */ + var new_sdist = new sdist(); + new_sdist.owning_lib(list[0]);//TODO: add multiple at once support? + new_sdist.isnew(1); + new_sdist.record_entry(obj.docid); + var params = {}; + params.sdists = [new_sdist]; + obj.editor_init('sdist', 'add', params); + } catch(E) { + obj.error.standard_unexpected_error_alert(document.getElementById('serialStrings').getString('staff.serial.manage_subs.add.error'),E); + } + } + ], + 'cmd_transfer_distribution' : [ + ['command'], + function() { + try { + obj.data.stash_retrieve(); + if (!obj.data.marked_library) { + alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.transfer_volume.alert')); + return; + } + + var list = obj.ids_from_sel_list('sdist'); + + netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite'); + + JSAN.use('util.functional'); + + var sdist_list = util.functional.map_list( + list, + function (o) { + return obj.map_sdist[ 'sdist_' + o ].start_date(); + } + ).join(document.getElementById('commonStrings').getString('common.grouping_string')); + + var xml = ''; + xml += ''; + xml += document.getElementById('catStrings').getFormattedString('staff.cat.copy_browser.transfer.prompt', [sdist_list, obj.data.hash.aou[ obj.data.marked_library.lib ].shortname()]); + xml += ''; + xml += '