[open-ils-commits] r16974 - in branches/seials-integration/Open-ILS: src/perlmods/OpenILS/Application xul/staff_client/server/serial (dbwells)
svn at svn.open-ils.org
svn at svn.open-ils.org
Sun Jul 18 17:55:43 EDT 2010
Author: dbwells
Date: 2010-07-18 17:55:37 -0400 (Sun, 18 Jul 2010)
New Revision: 16974
Added:
branches/seials-integration/Open-ILS/xul/staff_client/server/serial/manage_items.js
branches/seials-integration/Open-ILS/xul/staff_client/server/serial/manage_items.xul
Modified:
branches/seials-integration/Open-ILS/src/perlmods/OpenILS/Application/Serial.pm
branches/seials-integration/Open-ILS/xul/staff_client/server/serial/manage_subs.js
branches/seials-integration/Open-ILS/xul/staff_client/server/serial/manage_subs.xul
branches/seials-integration/Open-ILS/xul/staff_client/server/serial/serctrl_main.xul
Log:
- Initial draft commit of "Items" tab
- Basic working prediction support
- Enable multi-edit support for "Subscriptions" tab
- Simple SCAP and Issuance methods added
Modified: branches/seials-integration/Open-ILS/src/perlmods/OpenILS/Application/Serial.pm
===================================================================
--- branches/seials-integration/Open-ILS/src/perlmods/OpenILS/Application/Serial.pm 2010-07-18 14:44:18 UTC (rev 16973)
+++ branches/seials-integration/Open-ILS/src/perlmods/OpenILS/Application/Serial.pm 2010-07-18 21:55:37 UTC (rev 16974)
@@ -41,6 +41,7 @@
use base qw/OpenILS::Application/;
use OpenILS::Application::AppUtils;
use OpenSRF::AppSession;
+use OpenSRF::Utils qw/:datetime/;;
use OpenSRF::Utils::Logger qw($logger);
use OpenILS::Utils::CStoreEditor q/:funcs/;
use OpenILS::Utils::MFHD;
@@ -53,6 +54,9 @@
'864' => $MFHD_NAMES[1],
'855' => $MFHD_NAMES[2],
'865' => $MFHD_NAMES[2] );
+my %MFHD_TAGS_BY_NAME = ( $MFHD_NAMES[0] => '853',
+ $MFHD_NAMES[1] => '854',
+ $MFHD_NAMES[2] => '855');
# helper method for conforming dates to ISO8601
@@ -83,7 +87,7 @@
type => 'string'
},
{
- name => 'issuances',
+ name => 'items',
desc => 'Array of fleshed items',
type => 'array'
}
@@ -119,7 +123,7 @@
} elsif( $item->isnew ) {
# TODO: reconsider this
# if the item has a new issuance, create the issuance first
- if ($item->issuance->isnew) {
+ if (ref $item->issuance eq 'Fieldmapper::serial::issuance' and $item->issuance->isnew) {
fleshed_issuance_alter($self, $conn, $auth, [$item->issuance]);
}
_cleanse_dates($item, ['date_expected','date_received']);
@@ -288,7 +292,25 @@
return 0;
}
+__PACKAGE__->register_method(
+ method => "fleshed_serial_issuance_retrieve_batch",
+ authoritative => 1,
+ api_name => "open-ils.serial.issuance.fleshed.batch.retrieve"
+);
+sub fleshed_serial_issuance_retrieve_batch {
+ my( $self, $client, $ids ) = @_;
+# FIXME: permissions?
+ $logger->info("Fetching fleshed serial issuances @$ids");
+ return $U->cstorereq(
+ "open-ils.cstore.direct.serial.issuance.search.atomic",
+ { id => $ids },
+ { flesh => 1,
+ flesh_fields => {siss => [ qw/creator editor subscription/ ]}
+ });
+}
+
+
##########################################################################
# unit methods
#
@@ -391,83 +413,101 @@
# predict and receive methods
#
__PACKAGE__->register_method(
- method => 'generate_predictions',
- api_name => 'open-ils.serial.generate_predictions',
+ method => 'make_predictions',
+ api_name => 'open-ils.serial.make_predictions',
api_level => 1,
argc => 1,
signature => {
- desc => 'Receives an sre (serial record entry) id and returns an array ref of predicted issuances',
+ desc => 'Receives an ssub id and populates the issuance and item tables',
'params' => [ {
- name => 'sre_id',
- desc => 'Serial Record Entry ID',
- type => 'integer'
+ name => 'ssub_id',
+ desc => 'Serial Subscription ID',
+ type => 'int'
}
- ],
- 'return' => {
- desc => 'Returns predicted issuances',
- type => 'array'
- }
+ ]
}
);
-sub generate_predictions {
+sub make_predictions {
my ($self, $conn, $authtoken, $args) = @_;
my $editor = OpenILS::Utils::CStoreEditor->new();
- if (!exists($args->{sre_id})) { # lookup by sdist_id instead
- my $sdist = $editor->retrieve_serial_distribution([$args->{sdist_id}]);
- $args->{sre_id} = $sdist->record_entry;
- }
- #return $args->{sre_id};
- my $sre = $editor->retrieve_serial_record_entry([$args->{sre_id}]);
+ my $ssub_id = $args->{ssub_id};
+ my $mfhd = MFHD->new(MARC::Record->new());
- #return $sre->marc;
+ my $ssub = $editor->retrieve_serial_subscription([$ssub_id]);
+ my $scaps = $editor->search_serial_caption_and_pattern({ subscription => $ssub_id, active => 't'});
+ my $sdists = $editor->search_serial_distribution( [{ subscription => $ssub->id }, { flesh => 1,
+ flesh_fields => {sdist => [ qw/ streams / ]}, limit => 1 }] ); #TODO: 'deleted' support?
- #convert from marc_xml to marc
- my $marc = MARC::Record->new_from_xml($sre->marc);
-
- #turn into MFHD record object
- my $mfhd = MFHD->new($marc);
-
my @predictions;
- # TODO: consider support for predicting supplements/indexes (854/855)
- my $tag = '853';
- my @active_captions = $mfhd->active_captions($tag);
- foreach my $caption (@active_captions) {
+ my $link_id = 1;
+ foreach my $scap (@$scaps) {
+ my $caption_field = _revive_caption($scap);
+ $caption_field->update('8' => $link_id);
+ $mfhd->append_fields($caption_field);
my $options = {
- 'caption' => $caption,
- 'num_to_predict' => $args->{num_to_predict},
- 'last_rec_date' => $args->{last_rec_date}
+ 'caption' => $caption_field,
+ 'scap_id' => $scap->id,
+ 'num_to_predict' => $args->{num_to_predict}
+ #'last_rec_date' => $args->{last_rec_date}
};
- if ($args->{from_last_received}) {
- my $last_received = $editor->search_serial_issuance([
- { 'holding_type' => $MFHD_NAMES_BY_TAG{$tag},
- 'holding_link_id' => $caption->link_id,
- 'distribution' => $args->{sdist_id}},
- {limit => 1, order_by => { siss => "date_expected DESC" }}]
+ if ($args->{base_issuance}) { # predict from a given issuance
+ #$options->{last_rec_date} = $args->{base_issuance}->date_expected;
+ $options->{predict_from} = _revive_holding($args->{base_issuance}->holding_code, $caption_field, 1); # fresh MFHD Record, so we simply default to 1 for seqno
+ } else { # default to predicting from last published
+ my $last_published = $editor->search_serial_issuance([
+ {'caption_and_pattern' => $scap->id,
+ 'subscription' => $ssub_id},
+ {limit => 1, order_by => { siss => "date_published DESC" }}]
);
- if ($last_received->[0]) {
- $options->{last_rec_date} = $last_received->[0]->date_expected;
- $options->{predict_from} = _revive_holding($mfhd, $last_received->[0]->holding_code);
+ if ($last_published->[0]) {
+ my $last_siss = $last_published->[0];
+ #my $items_for_last_published = $editor->search_serial_item({'issuance' => $last_siss->id}, {limit => 1, order_by => { sitem => "date_expected ASC" }}); # assume later expected are exceptions, TODO: move this whole date offset idea to item creation portion, not issuance creation
+ #$options->{last_rec_date} = $items_for_last_published->[0]->date_expected;
+ $options->{predict_from} = _revive_holding($last_siss->holding_code, $caption_field, 1);
+ } else {
+ #TODO: throw event (can't predict from nothing!)
}
}
push( @predictions, _generate_issuance_values($mfhd, $options) );
+ $link_id++;
}
my @issuances;
foreach my $prediction (@predictions) {
my $issuance = new Fieldmapper::serial::issuance;
$issuance->isnew(1);
- $issuance->holding_link_id($prediction->[0]);
- $issuance->label($prediction->[1]);
- $issuance->date_published($prediction->[2]);
- $issuance->date_expected($prediction->[3]);
- $issuance->holding_code(OpenSRF::Utils::JSON->perl2JSON($prediction->[4]));
- $issuance->holding_type($prediction->[5]);
+ $issuance->label($prediction->{label});
+ $issuance->date_published($prediction->{date_published}->strftime('%F'));
+ $issuance->holding_code(OpenSRF::Utils::JSON->perl2JSON($prediction->{holding_code}));
+ $issuance->holding_type($prediction->{holding_type});
+ $issuance->caption_and_pattern($prediction->{caption_and_pattern});
+ $issuance->subscription($ssub->id);
push (@issuances, $issuance);
}
- return \@issuances;
+ fleshed_issuance_alter($self, $conn, $authtoken, \@issuances); # FIXME: catch events
+
+ my @items;
+ for (my $i = 0; $i < @issuances; $i++) {
+ my $date_expected = $predictions[$i]->{date_published}->add(seconds => interval_to_seconds($ssub->expected_date_offset))->strftime('%F');
+ my $issuance = $issuances[$i];
+ #$issuance->label(interval_to_seconds($ssub->expected_date_offset));
+ foreach my $sdist (@$sdists) {
+ my $streams = $sdist->streams;
+ foreach my $stream (@$streams) {
+ my $item = new Fieldmapper::serial::item;
+ $item->isnew(1);
+ $item->stream($stream->id);
+ $item->date_expected($date_expected);
+ $item->issuance($issuance->id);
+ push (@items, $item);
+ }
+ }
+ }
+ fleshed_item_alter($self, $conn, $authtoken, \@items); # FIXME: catch events
+ return \@items;
}
#
@@ -482,105 +522,117 @@
# The basic method is to first convert to a single holding if compressed, then
# increment the holding and save the resulting values to @issuances.
#
-# returns @issuance_values, an array of array refs containing (link id, formatted
+# returns @issuance_values, an array of hashrefs containing (formatted
# label, formatted chronology date, formatted estimated arrival date, and an
# array ref of holding subfields as (key, value, key, value ...)) (not a hash
-# to protect order and possible duplicate keys).
+# to protect order and possible duplicate keys), and a holding type.
#
sub _generate_issuance_values {
my ($mfhd, $options) = @_;
my $caption = $options->{caption};
+ my $scap_id = $options->{scap_id};
my $num_to_predict = $options->{num_to_predict};
- my $last_rec_date = $options->{last_rec_date}; # expected or actual, according to preference
- my $predict_from = $options->{predict_from}; # optional issuance to predict from
+ my $predict_from = $options->{predict_from}; # issuance to predict from
+ #my $last_rec_date = $options->{last_rec_date}; # expected or actual
# TODO: add support for predicting serials with no chronology by passing in
# a last_pub_date option?
- my $strp = new DateTime::Format::Strptime(pattern => '%F');
- my $receival_date = $strp->parse_datetime($last_rec_date);
+# Only needed for 'real' MFHD records, not our temp records
+# my $link_id = $caption->link_id;
+# if(!$predict_from) {
+# my $htag = $caption->tag;
+# $htag =~ s/^85/86/;
+# my @holdings = $mfhd->holdings($htag, $link_id);
+# my $last_holding = $holdings[-1];
+#
+# #if ($last_holding->is_compressed) {
+# # $last_holding->compressed_to_last; # convert to last in range
+# #}
+# $predict_from = $last_holding;
+# }
+#
- my $htag = $caption->tag;
- $htag =~ s/^85/86/;
- my $link_id = $caption->link_id;
- if(!$predict_from) {
- my @holdings = $mfhd->holdings($htag, $link_id);
- my $last_holding = $holdings[-1];
-
- if ($last_holding->is_compressed) {
- $last_holding->compressed_to_last; # convert to last in range
- }
- $predict_from = $last_holding;
- }
-
- my $pub_date = $strp->parse_datetime($predict_from->chron_to_date);
- my $date_diff = $receival_date - $pub_date;
-
$predict_from->notes('public', []);
-# add a note marker for system use
+# add a note marker for system use (?)
$predict_from->notes('private', ['AUTOGEN']);
+ my $strp = new DateTime::Format::Strptime(pattern => '%F');
+ my $pub_date;
my @issuance_values;
my @predictions = $mfhd->generate_predictions({'base_holding' => $predict_from, 'num_to_predict' => $num_to_predict});
foreach my $prediction (@predictions) {
$pub_date = $strp->parse_datetime($prediction->chron_to_date);
- my $arrival_date = $pub_date + $date_diff;
push(
@issuance_values,
- [
- $link_id,
- $prediction->format,
- $pub_date->strftime('%F'),
- $arrival_date->strftime('%F'),
- [$htag,$prediction->indicator(1),$prediction->indicator(2),$prediction->subfields_list],
- $MFHD_NAMES_BY_TAG{$caption->tag}
- ]
+ {
+ #$link_id,
+ label => $prediction->format,
+ date_published => $pub_date,
+ #date_expected => $date_expected->strftime('%F'),
+ holding_code => [$prediction->indicator(1),$prediction->indicator(2),$prediction->subfields_list],
+ holding_type => $MFHD_NAMES_BY_TAG{$caption->tag},
+ caption_and_pattern => $scap_id
+ }
);
}
return @issuance_values;
}
+sub _revive_caption {
+ my $scap = shift;
+
+ my $pattern_code = $scap->pattern_code;
+
+ # build MARC::Field
+ my $pattern_parts = OpenSRF::Utils::JSON->JSON2perl($pattern_code);
+ unshift(@$pattern_parts, $MFHD_TAGS_BY_NAME{$scap->type});
+ my $pattern_field = new MARC::Field(@$pattern_parts);
+
+ # build MFHD::Caption
+ return new MFHD::Caption($pattern_field);
+}
+
sub _revive_holding {
- my $mfhd = shift;
my $holding_code = shift;
+ my $caption_field = shift;
+ my $seqno = shift;
# build MARC::Field
my $holding_parts = OpenSRF::Utils::JSON->JSON2perl($holding_code);
- my $issuance_holding = new MARC::Field(@$holding_parts);
- # fetch matching captions
- my $captag = $issuance_holding->tag;
- $captag =~ s/^86/85/;
- my $captions_ref = $mfhd->captions($captag, 'hashref');
+ my $captag = $caption_field->tag;
+ $captag =~ s/^85/86/;
+ unshift(@$holding_parts, $captag);
+ my $holding_field = new MARC::Field(@$holding_parts);
+
# build MFHD::Holding
- my $link_subfield = $issuance_holding->subfield('8');
- my ($link_id, $seqno) = split(/\./, $link_subfield);
- return new MFHD::Holding($seqno, $issuance_holding, $captions_ref->{$link_id});
+ return new MFHD::Holding($seqno, $holding_field, $caption_field);
}
__PACKAGE__->register_method(
- method => 'receive_issuances',
- api_name => 'open-ils.serial.receive_issuances',
+ method => 'receive_items',
+ api_name => 'open-ils.serial.receive_items',
api_level => 1,
argc => 1,
signature => {
- desc => 'Marks an issuance as received, updates the shelving unit (creating a new shelving unit if needed), and updates the underlying MFHD record',
+ desc => 'Marks an item as received, updates the shelving unit (creating a new shelving unit if needed), and updates the summaries',
'params' => [ {
- name => 'issuances',
- desc => 'array of Issuance objects',
+ name => 'items',
+ desc => 'array of serial items',
type => 'array'
}
],
'return' => {
- desc => 'Returns number of received issuances',
+ desc => 'Returns number of received items',
type => 'int'
}
}
);
-sub receive_issuances {
- my ($self, $conn, $auth, $issuances) = @_;
+sub receive_items {
+ my ($self, $conn, $auth, $items) = @_;
my $last_distribution;
my $last_mfhd;
@@ -589,29 +641,26 @@
my( $reqr, $evt ) = $U->checkses($auth);
return $evt if $evt;
my $editor = new_editor(requestor => $reqr, xact => 1);
- foreach my $issuance (@$issuances) {
- # unflesh shelving unit if fleshed
- $issuance->shelving_unit( $issuance->shelving_unit->id ) if ref($issuance->shelving_unit);
- $issuance->distribution( $issuance->distribution->id ) if ref($issuance->distribution);
+ foreach my $item (@$items) {
+ # unflesh unit if fleshed
+ $item->unit( $item->unit->id ) if ref($item->unit);
- $issuance->copies_received($issuance->copies_received + 1);
- $issuance->copies_expected($issuance->copies_expected - 1);
- $issuance->date_received('now');
+ $item->date_received('now');
- # create shelving unit if needed
- if ($issuance->shelving_unit == -1) { # create by "volume" (first issuance division)
+ # create unit if needed
+ if ($item->unit == -1) { # create by "volume" (first item division)
#TODO
- } elsif ($issuance->shelving_unit == -2) { # create by "issue" (second issuance division)
+ } elsif ($item->unit == -2) { # create by "issue" (second item division)
#TODO
}
my $mfhd;
my $sre;
- if ($issuance->distribution == $last_distribution) {
+ if ($item->distribution == $last_distribution) {
# use cached record
$mfhd = $last_mfhd;
} else { # get MFHD record
- my $sdist = $editor->retrieve_serial_distribution([$issuance->distribution]);
+ my $sdist = $editor->retrieve_serial_distribution([$item->distribution]);
$sre = $editor->retrieve_serial_record_entry([$sdist->record_entry]);
#convert from marc_xml to marc
@@ -623,45 +672,33 @@
$mfhds_to_save{$sre->id} = $mfhd;
}
-# # build MARC::Field
-# my $holding_parts = OpenSRF::Utils::JSON->JSON2perl($issuance->holding_code);
-# my $issuance_holding = new MARC::Field(@$holding_parts);
-# # fetch matching captions
-# my $captag = $issuance_holding->tag;
-# $captag =~ s/^86/85/;
-# my $captions_ref = $mfhd->captions($captag, 'hashref');
-# # build MFHD::Holding
-# my $link_subfield = $issuance_holding->subfield('8');
-# my ($link_id, $seqno) = split(/\./, $link_subfield);
-# $issuance_holding = new MFHD::Holding($seqno, $issuance_holding, $captions_ref->{$link_id});
- my $issuance_holding = _revive_holding($mfhd, $issuance->holding_code);
+ my $item_holding = _revive_holding($mfhd, $item->holding_code);
# get all current holdings for this linked caption
-# my @curr_holdings = $mfhd->holdings($issuance_holding->tag, $link_id);
- my @curr_holdings = $mfhd->holdings($issuance_holding->tag, $issuance_holding->caption->link_id);
+ my @curr_holdings = $mfhd->holdings($item_holding->tag, $item_holding->caption->link_id);
# short-circuit logic : if holding is the next one, increment the last current holding
my $next_holding_values = $curr_holdings[-1]->next;
- if ($next_holding_values and $issuance_holding->matches($next_holding_values)) {
+ if ($next_holding_values and $item_holding->matches($next_holding_values)) {
$curr_holdings[-1]->extend;
} else { # not the next expected, do full replacement
- $mfhd->append_fields($issuance_holding);
+ $mfhd->append_fields($item_holding);
# my @updated_holdings = $mfhd->get_compressed_holdings($captions_ref->{$link_id});
- my @updated_holdings = $mfhd->get_compressed_holdings($issuance_holding->caption);
+ my @updated_holdings = $mfhd->get_compressed_holdings($item_holding->caption);
# set reference point to top of current holdings
my $marker_field = MARC::Field->new(500, '', '','a' => 'Temporary Marker');
$mfhd->insert_fields_before($curr_holdings[0], $marker_field);
foreach my $holding (@curr_holdings) {
$mfhd->delete_field($holding);
}
- $mfhd->delete_field($issuance_holding);
+ $mfhd->delete_field($item_holding);
$mfhd->insert_fields_before($marker_field, @updated_holdings);
# delete reference point
$mfhd->delete_field($marker_field);
}
- $last_distribution = $issuance->distribution;
+ $last_distribution = $item->distribution;
$last_mfhd = $mfhd;
- _update_issuance($editor, undef, $issuance);
+ _update_item($editor, undef, $item);
}
foreach my $sre_id (keys %sres_to_save) {
@@ -672,13 +709,10 @@
$sre->marc($xml);
$sre->ischanged(1);
$editor->update_serial_record_entry($sre);
- #return ($sre->record);
}
- #return OpenSRF::Utils::JSON->perl2JSON($last_mfhd);
-
$editor->commit;
- return scalar @$issuances;
+ return scalar @$items;
}
@@ -711,6 +745,19 @@
/
);
+__PACKAGE__->register_method(
+ method => 'fetch_notes',
+ api_name => 'open-ils.serial.distribution_note.retrieve.all',
+ signature => q/
+ Returns an array of copy note objects.
+ @param args A named hash of parameters including:
+ authtoken : Required if viewing non-public notes
+ distribution_id : The id of the item whose notes we want to retrieve
+ pub : True if all the caller wants are public notes
+ @return An array of note objects
+ /
+);
+
# TODO: revisit this method to consider replacing cstore direct calls
sub fetch_notes {
my( $self, $connection, $args ) = @_;
@@ -759,6 +806,17 @@
/
);
+__PACKAGE__->register_method(
+ method => 'create_note',
+ api_name => 'open-ils.serial.distribution_note.create',
+ signature => q/
+ Creates a new distribution note
+ @param authtoken The login session key
+ @param note The note object to create
+ @return The id of the new note object
+ /
+);
+
sub create_note {
my( $self, $connection, $authtoken, $note ) = @_;
@@ -811,6 +869,17 @@
/
);
+__PACKAGE__->register_method(
+ method => 'delete_note',
+ api_name => 'open-ils.serial.distribution_note.delete',
+ signature => q/
+ Deletes an existing distribution note
+ @param authtoken The login session key
+ @param noteid The id of the note to delete
+ @return 1 on success - Event otherwise.
+ /
+);
+
sub delete_note {
my( $self, $conn, $authtoken, $noteid ) = @_;
@@ -820,7 +889,8 @@
my $e = new_editor(xact=>1, authtoken=>$authtoken);
return $e->die_event unless $e->checkauth;
- my $note = $e->retrieve_serial_item_note([
+ my $method = "retrieve_serial_${type}_note";
+ my $note = $e->$method([
$noteid,
]) or return $e->die_event;
@@ -830,7 +900,7 @@
# $e->allowed('DELETE_COPY_NOTE', $note->item->call_number->owning_lib);
# }
- my $method = "delete_serial_${type}_note";
+ $method = "delete_serial_${type}_note";
$e->$method($note) or return $e->die_event;
$e->commit;
return 1;
@@ -907,6 +977,15 @@
sub _delete_ssub {
my ($editor, $override, $ssub) = @_;
$logger->info("subscription-alter: delete subscription ".OpenSRF::Utils::JSON->perl2JSON($ssub));
+ my $sdists = $editor->search_serial_distribution(
+ { subscription => $ssub->id }, { limit => 1 } ); #TODO: 'deleted' support?
+ my $cps = $editor->search_serial_caption_and_pattern(
+ { subscription => $ssub->id }, { limit => 1 } ); #TODO: 'deleted' support?
+ my $sisses = $editor->search_serial_issuance(
+ { subscription => $ssub->id }, { limit => 1 } ); #TODO: 'deleted' support?
+ return OpenILS::Event->new(
+ 'SERIAL_SUBSCRIPTION_NOT_EMPTY', payload => $ssub->id ) if (@$sdists or @$cps or @$sisses);
+
return $editor->event unless $editor->delete_serial_subscription($ssub);
return 0;
}
@@ -1175,8 +1254,119 @@
"open-ils.cstore.direct.serial.distribution.search.atomic",
{ id => $ids },
{ flesh => 1,
- flesh_fields => {sdist => [ qw/ holding_lib receive_call_number receive_unit_template bind_call_number bind_unit_template / ]}
+ flesh_fields => {sdist => [ qw/ holding_lib receive_call_number receive_unit_template bind_call_number bind_unit_template streams / ]}
});
}
+##########################################################################
+# caption and pattern methods
+#
+__PACKAGE__->register_method(
+ method => 'scap_alter',
+ api_name => 'open-ils.serial.caption_and_pattern.batch.update',
+ api_level => 1,
+ argc => 2,
+ signature => {
+ desc => 'Receives an array of one or more caption and patterns and updates the database as needed',
+ 'params' => [ {
+ name => 'authtoken',
+ desc => 'Authtoken for current user session',
+ type => 'string'
+ },
+ {
+ name => 'scaps',
+ desc => 'Array of caption and patterns',
+ type => 'array'
+ }
+
+ ],
+ 'return' => {
+ desc => 'Returns 1 if successful, event if failed',
+ type => 'mixed'
+ }
+ }
+);
+
+sub scap_alter {
+ my( $self, $conn, $auth, $scaps ) = @_;
+ return 1 unless ref $scaps;
+ 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 $scap (@$scaps) {
+ my $scapid = $scap->id;
+
+ if( $scap->isdeleted ) {
+ $evt = _delete_scap( $editor, $override, $scap);
+ } elsif( $scap->isnew ) {
+ $evt = _create_scap( $editor, $scap );
+ } else {
+ $evt = _update_scap( $editor, $override, $scap );
+ }
+ }
+
+ if( $evt ) {
+ $logger->info("caption_and_pattern-alter failed with event: ".OpenSRF::Utils::JSON->perl2JSON($evt));
+ $editor->rollback;
+ return $evt;
+ }
+ $logger->debug("caption_and_pattern-alter: done updating caption_and_pattern batch");
+ $editor->commit;
+ $logger->info("caption_and_pattern-alter successfully updated ".scalar(@$scaps)." caption_and_patterns");
+ return 1;
+}
+
+sub _delete_scap {
+ my ($editor, $override, $scap) = @_;
+ $logger->info("caption_and_pattern-alter: delete caption_and_pattern ".OpenSRF::Utils::JSON->perl2JSON($scap));
+ my $sisses = $editor->search_serial_issuance(
+ { caption_and_pattern => $scap->id }, { limit => 1 } ); #TODO: 'deleted' support?
+ return OpenILS::Event->new(
+ 'SERIAL_CAPTION_AND_PATTERN_HAS_ISSUANCES', payload => $scap->id ) if (@$sisses);
+
+ return $editor->event unless $editor->delete_serial_caption_and_pattern($scap);
+ return 0;
+}
+
+sub _create_scap {
+ my ($editor, $scap) = @_;
+
+ $logger->info("caption_and_pattern-alter: new caption_and_pattern ".OpenSRF::Utils::JSON->perl2JSON($scap));
+ return $editor->event unless $editor->create_serial_caption_and_pattern($scap);
+ return 0;
+}
+
+sub _update_scap {
+ my ($editor, $override, $scap) = @_;
+
+ $logger->info("caption_and_pattern-alter: retrieving caption_and_pattern ".$scap->id);
+ my $orig_scap = $editor->retrieve_serial_caption_and_pattern($scap->id);
+
+ $logger->info("caption_and_pattern-alter: original caption_and_pattern ".OpenSRF::Utils::JSON->perl2JSON($orig_scap));
+ $logger->info("caption_and_pattern-alter: updated caption_and_pattern ".OpenSRF::Utils::JSON->perl2JSON($scap));
+ return $editor->event unless $editor->update_serial_caption_and_pattern($scap);
+ return 0;
+}
+
+__PACKAGE__->register_method(
+ method => "serial_caption_and_pattern_retrieve_batch",
+ authoritative => 1,
+ api_name => "open-ils.serial.caption_and_pattern.batch.retrieve"
+);
+
+sub serial_caption_and_pattern_retrieve_batch {
+ my( $self, $client, $ids ) = @_;
+ $logger->info("Fetching caption_and_patterns @$ids");
+ return $U->cstorereq(
+ "open-ils.cstore.direct.serial.caption_and_pattern.search.atomic",
+ { id => $ids }
+ );
+}
+
1;
Added: branches/seials-integration/Open-ILS/xul/staff_client/server/serial/manage_items.js
===================================================================
--- branches/seials-integration/Open-ILS/xul/staff_client/server/serial/manage_items.js (rev 0)
+++ branches/seials-integration/Open-ILS/xul/staff_client/server/serial/manage_items.js 2010-07-18 21:55:37 UTC (rev 16974)
@@ -0,0 +1,691 @@
+dump('entering manage_items.js\n');
+
+function $(id) { return document.getElementById(id); }
+
+if (typeof serial == 'undefined') serial = {};
+serial.manage_items = function (params) {
+
+ JSAN.use('util.error'); this.error = new util.error();
+ JSAN.use('util.network'); this.network = new util.network();
+ JSAN.use('OpenILS.data'); this.data = new OpenILS.data(); this.data.init({'via':'stash'});
+}
+
+serial.manage_items.prototype = {
+
+ 'list_sitem_map' : {},
+
+ 'set_sdist_ids' : function () {
+ var obj = this;
+
+ try {
+ var holding_lib = $('serial_item_lib_menu').value;
+ robj = obj.network.request(
+ 'open-ils.pcrud',
+ 'open-ils.pcrud.id_list.sdist',
+ [ ses(), {"holding_lib" : holding_lib, "+ssub":{"record_entry" : obj.docid}}, {"join":"ssub"} ]
+ );
+ if (robj != null) {
+ if (typeof robj.ilsevent != 'undefined') throw(robj);
+ obj.sdist_ids = robj.length ? robj : [robj];
+ } else {
+ obj.sdist_ids = [];
+ }
+ } catch(E) {
+ obj.error.standard_unexpected_error_alert('set_sdist_ids failed!',E);
+ }
+ },
+
+ 'build_lib_menu' : function () {
+ var obj = this;
+
+ // draw library drop-down
+ obj.org_ids = obj.network.simple_request('FM_SSUB_AOU_IDS_RETRIEVE_VIA_RECORD_ID.authoritative',[ obj.docid ]);
+ if (typeof obj.org_ids.ilsevent != 'undefined') throw(obj.org_ids);
+ JSAN.use('util.functional');
+ obj.org_ids = util.functional.map_list( obj.org_ids, function (o) { return Number(o); });
+
+ var org = obj.data.hash.aou[ obj.data.list.au[0].ws_ou() ];
+
+ JSAN.use('util.file'); JSAN.use('util.widgets');
+
+ var file; var list_data; var ml;
+
+ file = new util.file('offline_ou_list');
+ if (file._file.exists()) {
+ list_data = file.get_object(); file.close();
+ ml = util.widgets.make_menulist( list_data[0], list_data[1] );
+ ml.setAttribute('id','serial_item_lib_menu'); document.getElementById('serial_item_lib_menu_box').appendChild(ml);
+ //TODO: class this menu properly
+ for (var i = 0; i < obj.org_ids.length; i++) {
+ ml.getElementsByAttribute('value',obj.org_ids[i])[0].setAttribute('class','has_distributions');
+ }
+ /*TODO: add/enable this legend?
+ ml.firstChild.addEventListener(
+ 'popupshown',
+ function(ev) {
+ document.getElementById('legend').setAttribute('hidden','false');
+ },
+ false
+ );
+ ml.firstChild.addEventListener(
+ 'popuphidden',
+ function(ev) {
+ document.getElementById('legend').setAttribute('hidden','true');
+ },
+ false
+ );*/
+ ml.addEventListener(
+ 'command',
+ function(ev) {
+ if (document.getElementById('serial_item_refresh_button')) document.getElementById('serial_item_refresh_button').focus();
+ JSAN.use('util.file'); var file = new util.file('manage_items_prefs.'+obj.data.server_unadorned);
+ util.widgets.save_attributes(file, { 'serial_item_lib_menu' : [ 'value' ], 'serial_manage_items_mode' : [ 'selectedIndex' ], 'serial_manage_items_show_all' : [ 'checked' ] }); //FIXME: do load_attributes somewhere and check if selectedIndex does what we want here
+ // get latest sdist id list based on library drowdown
+ obj.set_sdist_ids();
+ obj.refresh_list('main');
+ obj.refresh_list('sunit');
+ },
+ false
+ );
+ } else {
+ throw(document.getElementById('catStrings').getString('staff.cat.copy_browser.missing_library') + '\n');
+ }
+ file = new util.file('manage_items_prefs.'+obj.data.server_unadorned);
+ util.widgets.load_attributes(file);
+ ml.value = ml.getAttribute('value');
+ if (! ml.value) {
+ ml.value = org.id();
+ ml.setAttribute('value',ml.value);
+ }
+ },
+
+ 'init' : function( params ) {
+ var obj = this;
+
+ obj.docid = params['docid'];
+
+ obj.build_lib_menu();
+ obj.set_sdist_ids();
+ obj.init_lists();
+
+ JSAN.use('util.controller'); obj.controller = new util.controller();
+ obj.controller.init(
+ {
+ 'control_map' : {
+ 'save_columns' : [ [ 'command' ], function() { obj.lists.main.save_columns(); } ],
+ 'cmd_broken' : [ ['command'], function() { alert('Not Yet Implemented'); } ],
+ 'sel_clip' : [ ['command'], function() { obj.lists.main.clipboard(); } ],
+ 'cmd_add_item' : [
+ ['command'],
+ function() {
+ try {
+ var new_item = new sitem();
+ new_item.issuance(new siss());
+ new_item.stream(1); //FIXME: hard-coded stream
+ new_item.issuance().subscription(1); //FIXME: hard-coded subscription
+ new_item.isnew(1);
+ new_item.issuance().isnew(1);
+ spawn_item_editor( {'items' : [new_item], 'edit' : 1 } );
+
+ obj.refresh_list('main');
+
+ } catch(E) {
+ obj.error.standard_unexpected_error_alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.edit_items.error'),E);
+ }
+ }
+ ],
+ 'cmd_edit_items' : [
+ ['command'],
+ function() {
+ try {
+ if (!obj.retrieve_ids || obj.retrieve_ids.length == 0) return;
+
+ JSAN.use('util.functional');
+ var list = util.functional.map_list(
+ obj.retrieve_ids,
+ function (o) {
+ return o.sitem_id;
+ }
+ );
+
+ spawn_item_editor( { 'item_ids' : list, 'edit' : 1 } );
+
+ obj.refresh_list(obj.selected_list);
+
+ } catch(E) {
+ obj.error.standard_unexpected_error_alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.edit_items.error'),E);
+ }
+ }
+ ],
+ 'cmd_delete_items' : [
+ ['command'],
+ function() {
+ try {
+ JSAN.use('util.functional');
+ var list = util.functional.map_list(
+ obj.retrieve_ids,
+ function (o) {
+ return obj.list_sitem_map[o.sitem_id];
+ }
+ );
+ var delete_msg;
+ if (list.length != 1) {
+ delete_msg = document.getElementById('catStrings').getFormattedString('staff.cat.copy_browser.delete_items.confirm.plural', [list.length]);
+ } else {
+ delete_msg = document.getElementById('catStrings').getString('staff.cat.copy_browser.delete_items.confirm');
+ }
+ var r = obj.error.yns_alert(
+ delete_msg,
+ document.getElementById('catStrings').getString('staff.cat.copy_browser.delete_items.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',
+ 'open-ils.serial.item.fleshed.batch.update',
+ [ ses(), list, true ],
+ null,
+ {
+ 'title' : document.getElementById('catStrings').getString('staff.cat.copy_browser.delete_items.override'),
+ 'overridable_events' : [ // FIXME: replace or delete these events
+ 1208 /* TITLE_LAST_COPY */,
+ 1227 /* COPY_DELETE_WARNING */,
+ ]
+ }
+ );
+ if (robj == null) throw(robj);
+ if (typeof robj.ilsevent != 'undefined') {
+ if ( (robj.ilsevent != 0) && (robj.ilsevent != 1227 /* COPY_DELETE_WARNING */) && (robj.ilsevent != 1208 /* TITLE_LAST_COPY */) ) throw(robj);
+ }
+ obj.refresh_list(obj.selected_list);
+ }
+
+
+ } catch(E) {
+ obj.error.standard_unexpected_error_alert('staff.serial.manage_items.delete_items.error',E);
+ obj.refresh_list();
+ }
+ }
+ ],
+ 'cmd_predict_items' : [
+ ['command'],
+ function() {
+ alert('Subscription selection needed here'); //FIXME: make this prompt, or discard this feature
+ }
+ ],
+ 'cmd_receive_items' : [
+ ['command'],
+ function() {
+ try {
+ JSAN.use('util.functional');
+ var list = util.functional.map_list(
+ obj.retrieve_ids,
+ function (o) {
+ return obj.list_sitem_map[o.sitem_id];
+ }
+ );
+ for (var i = 0; i < list.length; i++) {
+ list[i].unit('1'); //FIXME: hard-coded unit
+ }
+
+ var robj = obj.network.request(
+ 'open-ils.serial',
+ 'open-ils.serial.receive_items',
+ [ ses(), list ]
+ );
+ if (typeof robj.ilsevent != 'undefined') throw(robj); //TODO: catch for override
+
+ alert('Successfully received '+robj+' item(s)');
+ obj.refresh_list('main');
+ obj.refresh_list('sunit');
+
+ } catch(E) {
+ obj.error.standard_unexpected_error_alert('cmd_receive_items failed!',E);
+ }
+ }
+ ],
+ 'cmd_edit_sunit' : [
+ ['command'],
+ function() {
+ try {
+ /*if (!obj.retrieve_ids || obj.retrieve_ids.length == 0) return;
+
+ JSAN.use('util.functional');
+ var list = util.functional.map_list(
+ obj.retrieve_ids,
+ function (o) {
+ return o.sitem_id;
+ }
+ );
+*/
+ spawn_sunit_editor( { 'sunit_ids' : [1], 'edit' : 1 } ); //FIXME: hard-coded sunit
+
+ } catch(E) {
+ obj.error.standard_unexpected_error_alert('cmd_edit_sunit failed!',E);
+ }
+ }
+ ],
+
+ 'cmd_items_print' : [ ['command'], function() { obj.items_print(obj.selected_list); } ],
+ 'cmd_items_export' : [ ['command'], function() { obj.items_export(obj.selected_list); } ],
+ 'cmd_refresh_list' : [ ['command'], function() { obj.refresh_list('main'); obj.refresh_list('sunit'); } ]
+ }
+ }
+ );
+
+ obj.retrieve('main'); // retrieve main list
+ obj.retrieve('sunit'); // retrieve shelving unit list
+
+ obj.controller.view.sel_clip.setAttribute('disabled','true');
+
+ },
+
+ 'items_print' : function(which) {
+ var obj = this;
+ try {
+ var list = obj.lists[which];
+/* FIXME: serial items print template? JSAN.use('patron.util');
+ var params = {
+ 'patron' : patron.util.retrieve_fleshed_au_via_id(ses(),obj.patron_id),
+ 'template' : 'items_out'
+ }; */
+ list.print( params );
+ } catch(E) {
+ obj.error.standard_unexpected_error_alert('manage_items printing',E);
+ }
+ },
+
+ 'items_export' : function(which) {
+ var obj = this;
+ try {
+ var list = obj.lists[which];
+ list.dump_csv_to_clipboard();
+ } catch(E) {
+ obj.error.standard_unexpected_error_alert('manage_items export',E);
+ }
+ },
+
+ 'init_lists' : function() {
+ var obj = this;
+
+ JSAN.use('circ.util');
+ var columns = item_columns({});
+
+ function retrieve_row(params) {
+ try {
+ var row = params.row;
+ obj.network.simple_request( //FIXME: pcrud fleshing won't work!!
+ 'FM_SITEM_RETRIEVE',
+ //[ ses(), row.my.sitem_id, {"flesh":1, "flesh_fields":{"sitem": ["creator","editor","distribution","shelving_unit"]}}],
+ [ ses(), row.my.sitem_id, {"flesh":2,"flesh_fields":{"sitem":["creator","editor","issuance","stream","unit","notes"], "sunit":["call_number"], "sstr":["distribution"]}}], // TODO: we really need note count only, not the actual notes, is there a smart way to do that?
+ function(req) {
+ try {
+ var robj = req.getResultObject();
+ if (typeof robj.ilsevent != 'undefined') throw(robj);
+ if (typeof robj.ilsevent == 'null') throw('null result');
+ obj.list_sitem_map[robj.id()] = robj;
+ row.my.sitem = robj;
+ //params.row_node.setAttribute( 'retrieve_id', js2JSON({'copy_id':copy_id,'circ_id':row.my.circ.id(),'barcode':row.my.acp.barcode(),'doc_id': ( row.my.record ? row.my.record.id() : null ) }) );
+ params.row_node.setAttribute( 'retrieve_id', js2JSON({'sitem_id':robj.id()}) );
+ dump('dumping... ' + js2JSON(obj.list_sitem_map[robj.id()]));
+ if (typeof params.on_retrieve == 'function') {
+ params.on_retrieve(row);
+ }
+
+ } catch(E) {
+ obj.error.standard_unexpected_error_alert('staff.serial.manage_items.retrieve_row.callback_error', E);
+ }
+ }
+ );
+ return row;
+ } catch(E) {
+ obj.error.standard_unexpected_error_alert('staff.serial.manage_items.retrieve_row.error_in_retrieve_row',E);
+ return params.row;
+ }
+ }
+
+ JSAN.use('util.list');
+
+ obj.lists = {};
+ obj.lists.main = new util.list('item_tree');
+ obj.lists.main.init(
+ {
+ 'columns' : columns,
+ 'map_row_to_columns' : circ.util.std_map_row_to_columns(),
+ 'retrieve_row' : retrieve_row,
+ 'on_select' : function(ev) {
+ obj.selected_list = 'main';
+ JSAN.use('util.functional');
+ var sel = obj.lists.main.retrieve_selection();
+ obj.controller.view.sel_clip.setAttribute('disabled',sel.length < 1);
+ var list = util.functional.map_list(
+ sel,
+ function(o) { return JSON2js( o.getAttribute('retrieve_id') ); }
+ );
+ if (typeof obj.on_select == 'function') {
+ obj.on_select(list);
+ }
+ if (typeof window.xulG == 'object' && typeof window.xulG.on_select == 'function') {
+ obj.error.sdump('D_CAT','manage_items: Calling external .on_select()\n');
+ window.xulG.on_select(list);
+ }
+ }
+ }
+ );
+ obj.lists.main.sitem_retrieve_params = {'date_received' : null };
+ obj.lists.main.sitem_sort_params ={'order_by' : {'sitem' : 'date_expected ASC'}};
+
+ obj.lists.sunit = new util.list('sunit_tree');
+ obj.lists.sunit.init(
+ {
+ 'columns' : columns,
+ 'map_row_to_columns' : circ.util.std_map_row_to_columns(),
+ 'retrieve_row' : retrieve_row,
+ 'on_select' : function(ev) {
+ obj.selected_list = 'sunit';
+ JSAN.use('util.functional');
+ var sel = obj.lists.sunit.retrieve_selection();
+ obj.controller.view.sel_clip.setAttribute('disabled',sel.length < 1);
+ var list = util.functional.map_list(
+ sel,
+ function(o) { return JSON2js( o.getAttribute('retrieve_id') ); }
+ );
+ if (typeof obj.on_select == 'function') {
+ obj.on_select(list);
+ }
+ if (typeof window.xulG == 'object' && typeof window.xulG.on_select == 'function') {
+ obj.error.sdump('D_CAT','serctrl: Calling external .on_select()\n');
+ window.xulG.on_select(list);
+ } else {
+ obj.error.sdump('D_CAT','serctrl: No external .on_select()\n');
+ }
+ }
+ }
+ );
+ obj.lists.sunit.sitem_retrieve_params = {'unit' : 1, 'date_received' : {"!=" : null}}; //FIXME: hard-coded shelving unit
+ obj.lists.sunit.sitem_sort_params ={'order_by' : {'sitem' : 'date_received DESC'}};
+ },
+
+ 'refresh_list' : function(list_name) {
+ var obj = this;
+
+ // TODO: make this change on the checkbox command event?
+ if (list_name == 'main') {
+ if (document.getElementById('serial_manage_items_show_all').checked) {
+ delete obj.lists.main.sitem_retrieve_params.date_received;
+ } else {
+ obj.lists.main.sitem_retrieve_params.date_received = null;
+ }
+ }
+ //TODO Optimize this?
+ obj.retrieve(list_name);
+ },
+
+ 'retrieve' : function(list_name) {
+ var obj = this;
+ var list = obj.lists[list_name];
+ if (window.xulG && window.xulG.items) {
+ obj.items = window.xulG.items;
+ } else {
+ obj.items = []; //FIXME: not using this
+
+ var rparams = list.sitem_retrieve_params;
+ var robj;
+ if (obj.sdist_ids.length > 0) {
+ rparams['+sstr'] = { "distribution" : {"in" : obj.sdist_ids} };
+ var other_params = list.sitem_sort_params;
+ other_params.join = 'sstr';
+
+ robj = obj.network.simple_request(
+ 'FM_SITEM_ID_LIST',
+ [ ses(), rparams, other_params ]
+ );
+ }
+/* if (typeof robj.ilsevent!='undefined') {
+ obj.error.standard_unexpected_error_alert('FIXME: Catch edit control with no distribution',E);
+ }*/
+ }
+ if (!robj) {
+ robj = [];
+ }else if (!robj.length) {
+ robj = [robj];
+ }
+
+ list.clear();
+
+ for (i = 0; i < robj.length; i++) {
+ list.append( { 'row' : { 'my' : { 'sitem_id' : robj[i] } }, 'to_bottom' : true, 'no_auto_select' : true } );
+ }
+ },
+
+ 'on_select' : function(list) {
+
+ dump('manage_items.on_select list = ' + js2JSON(list) + '\n');
+
+ var obj = this;
+
+ obj.retrieve_ids = list;
+ }
+}
+
+function item_columns(modify,params) {
+
+ JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
+ //JSAN.use('util.network'); var network = new util.network();
+
+ var c = [
+ {
+ 'id' : 'sitem_id',
+ 'label' : 'Item ID',
+ 'flex' : 1,
+ 'primary' : false,
+ 'hidden' : false,
+ 'render' : function(my) { return my.sitem.id(); },
+ 'persist' : 'hidden width ordinal'
+ },
+ {
+ 'id' : 'creator',
+ 'label' : 'Creator',
+ 'flex' : 1,
+ 'primary' : false,
+ 'hidden' : true,
+ 'persist' : 'hidden width ordinal',
+ 'render' : function(my) { return my.sitem.creator().usrname(); }
+ },
+ {
+ 'id' : 'create_date',
+ 'label' : document.getElementById('circStrings').getString('staff.circ.utils.create_date'),
+ 'flex' : 1,
+ 'primary' : false,
+ 'hidden' : true,
+ 'persist' : 'hidden width ordinal',
+ 'render' : function(my) { return my.sitem.create_date().substr(0,10); }
+ },
+ {
+ 'id' : 'editor',
+ 'label' : 'Editor',
+ 'flex' : 1,
+ 'primary' : false,
+ 'hidden' : false,
+ 'persist' : 'hidden width ordinal',
+ 'render' : function(my) { return my.sitem.editor().usrname(); }
+ },
+ {
+ 'id' : 'edit_date',
+ 'label' : document.getElementById('circStrings').getString('staff.circ.utils.edit_date'),
+ 'flex' : 1,
+ 'primary' : false,
+ 'hidden' : false,
+ 'persist' : 'hidden width ordinal',
+ 'render' : function(my) { return my.sitem.edit_date().substr(0,10); }
+ },
+ {
+ 'id' : 'distribution',
+ 'label' : 'Distribution',
+ 'flex' : 1,
+ 'primary' : false,
+ 'hidden' : true,
+ 'persist' : 'hidden width ordinal',
+ 'render' : function(my) { return my.sitem.stream().distribution().label(); }
+ },
+ {
+ 'id' : 'unit',
+ 'label' : 'Unit',
+ 'flex' : 1,
+ 'primary' : false,
+ 'hidden' : false,
+ 'persist' : 'hidden width ordinal',
+ 'render' : function(my) { return my.sitem.unit().call_number().label(); }
+ },
+ {
+ 'id' : 'label',
+ 'label' : 'Issuance Label',
+ 'flex' : 1,
+ 'primary' : false,
+ 'hidden' : false,
+ 'render' : function(my) { return my.sitem.issuance().label(); },
+ 'persist' : 'hidden width ordinal'
+ },
+ {
+ 'id' : 'date_published',
+ 'label' : 'Date Published',
+ 'flex' : 1,
+ 'primary' : false,
+ 'hidden' : false,
+ 'render' : function(my) { return my.sitem.issuance().date_published().substr(0,10); },
+ 'persist' : 'hidden width ordinal'
+ },
+ {
+ 'id' : 'date_expected',
+ 'label' : 'Date Expected',
+ 'flex' : 1,
+ 'primary' : false,
+ 'hidden' : false,
+ 'render' : function(my) { return my.sitem.date_expected().substr(0,10); },
+ 'persist' : 'hidden width ordinal'
+ },
+ {
+ 'id' : 'date_received',
+ 'label' : 'Date Received',
+ 'flex' : 1,
+ 'primary' : false,
+ 'hidden' : false,
+ 'render' : function(my) { return my.sitem.date_received().substr(0,10); },
+ 'persist' : 'hidden width ordinal'
+ },
+ {
+ 'id' : 'notes',
+ 'label' : 'Notes',
+ 'flex' : 1,
+ 'primary' : false,
+ 'hidden' : false,
+ 'render' : function(my) { return my.sitem.notes().length; },
+ 'persist' : 'hidden width ordinal'
+ },
+ {
+ 'id' : 'holding_code',
+ 'label' : 'Holding Code',
+ 'flex' : 1,
+ 'primary' : false,
+ 'hidden' : true,
+ 'render' : function(my) { return my.sitem.issuance().holding_code(); },
+ 'persist' : 'hidden width ordinal'
+ },
+ {
+ 'id' : 'holding_type',
+ 'label' : 'Holding Type',
+ 'flex' : 1,
+ 'primary' : false,
+ 'hidden' : true,
+ 'render' : function(my) { return my.sitem.issuance().holding_type(); },
+ 'persist' : 'hidden width ordinal'
+ },
+ {
+ 'id' : 'holding_link_id',
+ 'label' : 'Holding Link ID',
+ 'flex' : 1,
+ 'primary' : false,
+ 'hidden' : true,
+ 'render' : function(my) { return my.sitem.issuance().holding_link_id(); },
+ 'persist' : 'hidden width ordinal'
+ }
+ ];
+ for (var i = 0; i < c.length; i++) {
+ if (modify[ c[i].id ]) {
+ for (var j in modify[ c[i].id ]) {
+ c[i][j] = modify[ c[i].id ][j];
+ }
+ }
+ }
+ if (params) {
+ if (params.just_these) {
+ JSAN.use('util.functional');
+ var new_c = [];
+ for (var i = 0; i < params.just_these.length; i++) {
+ var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
+ new_c.push( function(y){ return y; }( x ) );
+ }
+ c = new_c;
+ }
+ if (params.except_these) {
+ JSAN.use('util.functional');
+ var new_c = [];
+ for (var i = 0; i < c.length; i++) {
+ var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
+ if (!x) new_c.push(c[i]);
+ }
+ c = new_c;
+ }
+ }
+ //return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
+ return c;
+};
+
+spawn_item_editor = function(params) {
+ try {
+ if (!params.item_ids && !params.items) return;
+ if (params.item_ids && params.item_ids.length == 0) return;
+ if (params.items && params.items.length == 0) return;
+ if (params.item_ids) params.item_ids = js2JSON(params.item_ids); // legacy
+ if (!params.caller_handles_update) params.handle_update = 1; // legacy
+
+ var obj = {};
+ JSAN.use('util.network'); obj.network = new util.network();
+ JSAN.use('util.error'); obj.error = new util.error();
+
+ var title = '';
+ if (params.item_ids && params.item_ids.length > 1 && params.edit == 1)
+ title = 'Batch Edit Items';
+ else /* if(params.copies && params.copies.length > 1 && params.edit == 1)
+ title = 'Batch View Items';
+ else if(params.item_ids && params.item_ids.length == 1) */
+ title = 'Edit Item';/*
+ else
+ title = 'View Item';*/
+
+ JSAN.use('util.window'); var win = new util.window();
+ var my_xulG = win.open(
+ (urls.XUL_SERIAL_ITEM_EDITOR),
+ title,
+ 'chrome,modal,resizable',
+ params
+ );
+ if (my_xulG.items && params.edit) {
+ return my_xulG.items;
+ } else {
+ return [];
+ }
+ } catch(E) {
+ JSAN.use('util.error'); var error = new util.error();
+ error.standard_unexpected_error_alert('error in spawn_item_editor',E);
+ }
+}
+
+dump('exiting manage_items.js\n');
Added: branches/seials-integration/Open-ILS/xul/staff_client/server/serial/manage_items.xul
===================================================================
--- branches/seials-integration/Open-ILS/xul/staff_client/server/serial/manage_items.xul (rev 0)
+++ branches/seials-integration/Open-ILS/xul/staff_client/server/serial/manage_items.xul 2010-07-18 21:55:37 UTC (rev 16974)
@@ -0,0 +1,135 @@
+<?xml version="1.0"?>
+<!-- Application: Evergreen Staff Client -->
+<!-- Screen: Manage Items Overlay -->
+<!--
+vim:noet:sw=4:ts=4:
+-->
+<!DOCTYPE overlay PUBLIC "" ""[
+ <!--#include virtual="/opac/locale/${locale}/lang.dtd"-->
+]>
+
+<overlay id="serial_manage_items_overlay"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <script type="text/javascript" src="/xul/server/serial/manage_items.js"/>
+ <script>
+ <![CDATA[
+ function my_init() {
+ try {
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+ if (typeof JSAN == 'undefined') {
+ throw( document.getElementById("commonStrings").getString('common.jsan.missing') );
+ }
+ JSAN.errorLevel = "die"; // none, warn, or die
+ JSAN.addRepository('/xul/server/');
+ JSAN.use('util.error'); g.error = new util.error();
+ g.error.sdump('D_TRACE','my_init() for manage_items.xul');
+
+ JSAN.use('serial.manage_items'); g.manage_items = new serial.manage_items();
+
+ //g.manage_items.init( { 'sre_id' : xul_param('sre_id'), 'sdist_id' : xul_param('sdist_id') } );
+ g.manage_items.init( { 'docid' : xul_param('docid') } );
+
+ } catch(E) {
+ var err_msg = document.getElementById("commonStrings").getFormattedString('common.exception', ['serial/manage_items.xul', E]);
+ try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); }
+ alert(err_msg);
+ }
+ }
+
+ ]]>
+ </script>
+ <popupset>
+ <popup id="serial_manage_items_popup">
+ <menuitem command="cmd_edit_items" label="Edit Item Attributes" accesskey="&staff.cat.copy_browser.actions.cmd_edit_items.accesskey;"/>
+ <menuitem command="cmd_delete_items" label="Delete Item" accesskey="&staff.cat.copy_browser.actions.cmd_delete_items.accesskey;"/>
+ </popup>
+ </popupset>
+ <tabpanel id="serial_manage_items" orient="vertical" flex="1">
+ <hbox align="center">
+ <hbox id="serial_item_lib_menu_box"/>
+ <label value="Mode:" control="mode_receive"/><radiogroup id="serial_manage_items_mode" orient="horizontal"><radio id="mode_receive" label="Receive"/><radio id="mode_bind" label="Bind"/></radiogroup><checkbox id="serial_manage_items_show_all" label="Show All" />
+ <button id="refresh_button" label="&staff.cat.copy_browser.holdings_maintenance.refresh_button.label;" command="cmd_refresh_list" />
+ <spacer flex="1"/>
+ <menubar>
+ <menu label="Actions for this Serial Control" accesskey="C">
+ <menupopup>
+ <menuitem command="cmd_predict_items" label="Predict Items"/>
+ <menuitem command="cmd_add_item" label="Add Custom Item"/>
+ <menuitem command="cmd_edit_mfhd" label="Edit MFHD Record"/>
+ </menupopup>
+ </menu>
+ <menu label="&staff.cat.copy_browser.holdings_maintenance.actions.label;" accesskey="&staff.cat.copy_browser.holdings_maintenance.actions.accesskey;">
+ <menupopup>
+ <menuitem command="cmd_edit_items" label="Edit Item Attributes" accesskey="&staff.cat.copy_browser.actions.cmd_edit_items.accesskey;"/>
+ <menuitem command="cmd_delete_items" label="Delete Item" accesskey="&staff.cat.copy_browser.actions.cmd_delete_items.accesskey;"/>
+ <menuseparator/>
+ <menuitem command="cmd_refresh_list" label="&staff.cat.copy_browser.holdings_maintenance.cmd_refresh_list.label;" accesskey="&staff.cat.copy_browser.holdings_maintenance.cmd_refresh_list.accesskey;"/>
+ <menuitem command="save_columns" label="&staff.cat.copy_browser.holdings_maintenance.save_columns.label;"/>
+ <!-- <menuitem command="sel_clip" label="&staff.cat.copy_browser.holdings_maintenance.sel_clip.label;" accesskey="&staff.cat.copy_browser.holdings_maintenance.sel_clip.accesskey;"/>
+ <menuitem command="cmd_transfer_items" label="&staff.cat.copy_browser.holdings_maintenance.cmd_transfer_items.label;" accesskey="&staff.cat.copy_browser.holdings_maintenance.cmd_transfer_items.accesskey;"/>
+ <menuseparator/>
+ <menuitem command="cmd_add_volumes" label="&staff.cat.copy_browser.holdings_maintenance.cmd_add_volumes.label;" accesskey="&staff.cat.copy_browser.holdings_maintenance.cmd_add_volumes.accesskey;"/>
+ <menuitem command="cmd_edit_volumes" label="&staff.cat.copy_browser.holdings_maintenance.cmd_edit_volumes.label;" accesskey="&staff.cat.copy_browser.holdings_maintenance.cmd_edit_volumes.accesskey;"/>
+ <menuitem command="cmd_mark_volume" label="&staff.cat.copy_browser.holdings_maintenance.cmd_mark_volume.label;" accesskey="&staff.cat.copy_browser.holdings_maintenance.cmd_mark_volume.accesskey;"/>
+ <menuitem command="cmd_transfer_volume" label="&staff.cat.copy_browser.holdings_maintenance.cmd_transfer_volume.label;" accesskey="&staff.cat.copy_browser.holdings_maintenance.cmd_transfer_volume.accesskey;"/>
+ <menuitem command="cmd_delete_volumes" label="&staff.cat.copy_browser.holdings_maintenance.cmd_delete_volumes.label;" accesskey=""/>
+ <menuseparator/>
+ <menuitem command="cmd_print_spine_labels" label="&staff.cat.copy_browser.holdings_maintenance.cmd_print_spine_labels.label;" accesskey="&staff.cat.copy_browser.holdings_maintenance.cmd_print_spine_labels.accesskey;"/>
+ <menuitem command="cmd_replace_barcode" label="&staff.cat.copy_browser.holdings_maintenance.cmd_replace_barcode.label;" accesskey=""/> -->
+ </menupopup>
+ </menu>
+ </menubar>
+ </hbox>
+ <tree id="item_tree" flex="2" enableColumnDrag="true" context="serial_manage_items_popup"/>
+ <splitter state="open" collapse="after" resizebefore="closest" resizeafter="farthest"/>
+ <hbox align="center">
+ <description value="Current Unit"/>
+ <spacer flex="1"/>
+ <!--<description value="Copy"/>
+ <menulist editable="true">
+ <menupopup>
+ <menuitem label="Auto Copy" value="AUTO"/>
+ <menuitem label="New Copy" value="NEW"/>
+ <menuitem label="(list copies) ######"/>
+ </menupopup>
+ </menulist>-->
+ <button label="Receive/Move Selected ↓" command="cmd_receive_items"/>
+ <description value="into"/>
+ <description value="[V.135]"/>
+ <!--<menulist label="Auto - Top Level">
+ <menupopup>
+ <menuitem label="Auto per Volume" selected="true"/>
+ <menuitem label="Auto per Issue"/>
+ <menuitem label="TEST1234"/>
+ </menupopup>
+ </menulist>-->
+ <menubar>
+ <menu label="Set Current Unit">
+ <menupopup>
+ <menu label="Recent">
+ <menupopup>
+ <menuitem command="cmd_broken" label="V.1"/>
+ <menuitem command="cmd_broken" label="V.2"/>
+ </menupopup>
+ </menu>
+ <menu label="Frequent">
+ <menupopup>
+ <menuitem command="cmd_broken" label="V.1"/>
+ <menuitem command="cmd_broken" label="V.2"/>
+ </menupopup>
+ </menu>
+ <menuitem command="cmd_broken" label="Other..."/>
+ </menupopup>
+ </menu>
+ <menu label="Actions for Units">
+ <menupopup>
+ <menuitem command="cmd_edit_sunit" label="Edit Current Unit..."/>
+ <menuitem command="cmd_broken" label="Manage Units..."/>
+ </menupopup>
+ </menu>
+ </menubar>
+ </hbox>
+ <tree id="sunit_tree" flex="1" enableColumnDrag="true" context="serial_manage_items_popup"/>
+ </tabpanel>
+
+</overlay>
Modified: branches/seials-integration/Open-ILS/xul/staff_client/server/serial/manage_subs.js
===================================================================
--- branches/seials-integration/Open-ILS/xul/staff_client/server/serial/manage_subs.js 2010-07-18 14:44:18 UTC (rev 16973)
+++ branches/seials-integration/Open-ILS/xul/staff_client/server/serial/manage_subs.js 2010-07-18 21:55:37 UTC (rev 16974)
@@ -24,6 +24,8 @@
'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,
@@ -185,7 +187,6 @@
['command'],
function() {
try {
- JSAN.use('util.functional');
var list = obj.ids_from_sel_list('ssub');
if (list.length == 0) return;
@@ -223,7 +224,6 @@
['command'],
function() {
try {
- JSAN.use('util.functional');
var list = obj.ids_from_sel_list('ssub');
if (list.length == 0) return;
@@ -261,7 +261,6 @@
['command'],
function() {
try {
- JSAN.use('util.functional');
var list = obj.ids_from_sel_list('ssub');
if (list.length == 0) list = obj.ids_from_sel_list('sdist-group');
if (list.length == 0) return;
@@ -454,7 +453,6 @@
['command'],
function() {
try {
- JSAN.use('util.functional');
var list = obj.ids_from_sel_list('aou');
if (list.length == 0) return;
//TODO: permission check?
@@ -500,12 +498,12 @@
return;
}
- JSAN.use('util.functional');
-
var list = obj.ids_from_sel_list('ssub');
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
+ JSAN.use('util.functional');
+
var ssub_list = util.functional.map_list(
list,
function (o) {
@@ -609,6 +607,62 @@
obj.refresh_list();
}
],
+ 'cmd_make_predictions' : [
+ ['command'],
+ function() {
+ try {
+ var list = obj.ids_from_sel_list('ssub');
+ if (list.length == 0) {
+ alert('You must select a subscription before predicting issuances.'); //TODO: better error
+ return;
+ }
+
+ var num_to_predict = prompt('How many items would you like to predict?',
+ '12',
+ 'Number of Predicted Items');
+ num_to_predict = String( num_to_predict ).replace(/\D/g,'');
+ if (num_to_predict == '') {
+ alert('Invalid number entered!'); //TODO: better error
+ return;
+ }
+
+ for (i = 0; i < list.length; i++) {
+ var robj = obj.network.request(
+ 'open-ils.serial',
+ 'open-ils.serial.make_predictions',
+ [ ses(), {"ssub_id":list[i], "num_to_predict":num_to_predict, "last_rec_date":"2010-07-07"}]
+ );
+ util.functional.map_list(
+ robj,
+ function(o) {
+ alert('debug: ' + o.date_expected());
+ }
+ );
+ }
+ return;
+
+ /*JSAN.use('util.functional');
+ var list = util.functional.map_list(
+ robj,
+ function (o) {
+ o.distribution(obj.sdist_id);
+ return o;
+ }
+ );*/
+
+ var robj = obj.network.request(
+ 'open-ils.serial',
+ 'open-ils.serial.item.fleshed.batch.update',
+ [ ses(), list ]
+ );
+
+ //obj.refresh_list('main');
+
+ } catch(E) {
+ obj.error.standard_unexpected_error_alert('cmd_make_predictions failed!',E);
+ }
+ }
+ ],
/*dbw2 'sel_distribution_details' : [
['command'],
function() {
@@ -1071,20 +1125,30 @@
'on_select' : function(list,twisty) {
var obj = this;
+ var sel_lists = {};
+
for (var i = 0; i < list.length; i++) {
- var node = obj.map_tree[ list[i] ];
var row_type = list[i].split('_')[0];
var id = list[i].split('_')[1];
- switch(row_type) {
- case 'aou' : obj.on_select_org(id,twisty); break;
- case 'ssub' : obj.on_select_ssub(id,twisty); break;
- case 'sdist' : obj.on_select_sdist(id,twisty); break;
- case 'siss' : obj.on_select_siss(id,twisty); break;
- case 'scap' : obj.on_select_scap(id,twisty); break;
- default: break;
+ if (!sel_lists[row_type]) sel_lists[row_type] = [];
+ sel_lists[row_type].push(id);
+
+ if (twisty) {
+ switch(row_type) {
+ case 'aou' : obj.on_select_org(id,twisty); break;
+ case 'ssub' : obj.on_select_ssub(id,twisty); break;
+ default: break;
+ }
}
}
+
+ var row_type = obj.focused_node_retrieve_id.split('_')[0];
+ var id = obj.focused_node_retrieve_id.split('_')[1];
+
+ if (sel_lists[row_type]) { // the type focused is in the selection (usually the case)
+ obj['on_click_' + row_type](sel_lists[row_type],twisty);
+ }
},
'on_select_ssub' : function(ssub_id,twisty) {
@@ -1135,11 +1199,18 @@
document.getElementById('cmd_show_libs_with_distributions').setAttribute('disabled','false');
document.getElementById('lib_menu').setAttribute('disabled','false');
} );
+ } catch(E) {
+ alert(E);
+ }
+ },
- // draw ssub editor
+ 'on_click_ssub' : function(ssub_ids,twisty) {
+ var obj = this;
+ try {
+ // draw sdist editor
if (typeof twisty == 'undefined') {
var params = {};
- params.ssub_ids = [ssub_id];
+ params.ssub_ids = ssub_ids;
obj.editor_init('ssub', 'edit', params);
}
} catch(E) {
@@ -1147,13 +1218,13 @@
}
},
- 'on_select_sdist' : function(sdist_id,twisty) {
+ 'on_click_sdist' : function(sdist_ids,twisty) {
var obj = this;
try {
// draw sdist editor
if (typeof twisty == 'undefined') {
var params = {};
- params.sdist_ids = [sdist_id];
+ params.sdist_ids = sdist_ids;
obj.editor_init('sdist', 'edit', params);
}
} catch(E) {
@@ -1161,13 +1232,13 @@
}
},
- 'on_select_siss' : function(siss_id,twisty) {
+ 'on_click_siss' : function(siss_ids,twisty) {
var obj = this;
try {
// draw siss editor
if (typeof twisty == 'undefined') {
var params = {};
- params.siss_ids = [siss_id];
+ params.siss_ids = siss_ids;
obj.editor_init('siss', 'edit', params);
}
} catch(E) {
@@ -1175,13 +1246,13 @@
}
},
- 'on_select_scap' : function(scap_id,twisty) {
+ 'on_click_scap' : function(scap_ids,twisty) {
var obj = this;
try {
// draw scap editor
if (typeof twisty == 'undefined') {
var params = {};
- params.scap_ids = [scap_id];
+ params.scap_ids = scap_ids;
obj.editor_init('scap', 'edit', params);
}
} catch(E) {
@@ -1482,7 +1553,7 @@
'id' : 'tree_location',
'label' : document.getElementById('catStrings').getString('staff.cat.copy_browser.list_init.tree_location'),
'flex' : 1, 'primary' : true, 'hidden' : false,
- 'render' : function(my) { return my.sdist ? my.sdist.label() : my.siss ? my.siss.label() : my.scap ? 'C/P #:' + my.scap.id() : my.ssub ? 'Subscription #:' + my.ssub.id() : my.aou ? my.aou.shortname() + " : " + my.aou.name() : my.label ? my.label : "???"; },
+ 'render' : function(my) { return my.sdist ? my.sdist.label() : my.siss ? my.siss.label() : my.scap ? 'C/P : #' + my.scap.id() : my.ssub ? 'Subscription : #' + my.ssub.id() : my.aou ? my.aou.shortname() + " : " + my.aou.name() : my.label ? my.label : "???"; },
},
{
'id' : 'subscription_count',
@@ -1523,7 +1594,8 @@
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserRead');
var row = {}; var col = {}; var nobj = {};
obj.list.node.treeBoxObject.getCellAt(ev.clientX,ev.clientY,row,col,nobj);
- if ((row.value == -1)||(nobj.value != 'twisty')) { return; }
+ if ((row.value == -1)||(nobj.value != 'twisty')) { return; } // on_click runs for twistys only
+
var node = obj.list.node.contentView.getItemAtIndex(row.value);
var list = [ node.getAttribute('retrieve_id') ];
if (typeof obj.on_select == 'function') {
@@ -1535,6 +1607,11 @@
},
'on_select' : function(ev) {
JSAN.use('util.functional');
+
+ // get the actual node clicked to determine which editor to use
+ var node = obj.list.node.contentView.getItemAtIndex(obj.list.node.view.selection.currentIndex);
+ obj.focused_node_retrieve_id = node.getAttribute('retrieve_id');
+
var sel = obj.list.retrieve_selection();
obj.controller.view.sel_clip.disabled = sel.length < 1;
obj.sel_list = util.functional.map_list(
@@ -1585,6 +1662,7 @@
obj.controller.view.cmd_add_sdist.setAttribute('disabled','true');
obj.controller.view.cmd_add_siss.setAttribute('disabled','true');
obj.controller.view.cmd_add_scap.setAttribute('disabled','true');
+ obj.controller.view.cmd_make_predictions.setAttribute('disabled','true');
obj.controller.view.cmd_delete_sdist.setAttribute('disabled','true');
obj.controller.view.cmd_delete_siss.setAttribute('disabled','true');
obj.controller.view.cmd_delete_scap.setAttribute('disabled','true');
@@ -1605,6 +1683,7 @@
obj.controller.view.cmd_add_siss.setAttribute('disabled','false');
obj.controller.view.cmd_add_scap.setAttribute('disabled','false');
obj.controller.view.cmd_transfer_subscription.setAttribute('disabled','false');
+ obj.controller.view.cmd_make_predictions.setAttribute('disabled','false');
}
if (found_sdist_group) {
obj.controller.view.cmd_add_sdist.setAttribute('disabled','false');
Modified: branches/seials-integration/Open-ILS/xul/staff_client/server/serial/manage_subs.xul
===================================================================
--- branches/seials-integration/Open-ILS/xul/staff_client/server/serial/manage_subs.xul 2010-07-18 14:44:18 UTC (rev 16973)
+++ branches/seials-integration/Open-ILS/xul/staff_client/server/serial/manage_subs.xul 2010-07-18 21:55:37 UTC (rev 16974)
@@ -55,6 +55,7 @@
<menuitem command="cmd_add_sdist" label="Add Distribution"/>
<menuitem command="cmd_add_siss" label="Add Issuance"/>
<menuitem command="cmd_add_scap" label="Add Caption/Pattern"/>
+ <menuitem command="cmd_make_predictions" label="Make Predictions"/>
<menuitem command="cmd_delete_ssub" label="Delete Subscription"/>
<menuitem command="cmd_delete_sdist" label="Delete Distribution"/>
<menuitem command="cmd_delete_siss" label="Delete Issuance"/>
@@ -77,6 +78,7 @@
<menuitem command="cmd_add_sdist" label="Add Distribution"/>
<menuitem command="cmd_add_siss" label="Add Issuance"/>
<menuitem command="cmd_add_scap" label="Add Caption/Pattern"/>
+ <menuitem command="cmd_make_predictions" label="Make Predictions"/>
<menuitem command="cmd_delete_ssub" label="Delete Subscription"/>
<menuitem command="cmd_delete_sdist" label="Delete Distribution"/>
<menuitem command="cmd_delete_siss" label="Delete Issuance"/>
Modified: branches/seials-integration/Open-ILS/xul/staff_client/server/serial/serctrl_main.xul
===================================================================
--- branches/seials-integration/Open-ILS/xul/staff_client/server/serial/serctrl_main.xul 2010-07-18 14:44:18 UTC (rev 16973)
+++ branches/seials-integration/Open-ILS/xul/staff_client/server/serial/serctrl_main.xul 2010-07-18 21:55:37 UTC (rev 16974)
@@ -59,9 +59,10 @@
<command id="cmd_delete_sdist"/>
<command id="cmd_delete_siss"/>
<command id="cmd_delete_ssub"/>
+ <command id="cmd_make_predictions"/>
<command id="cmd_mark_library"/>
<command id="cmd_mark_subscription"/>
- <command id="cmd_predict_items"/>
+ <!--<command id="cmd_predict_items"/>-->
<command id="cmd_print_spine_labels"/>
<command id="cmd_receive_items"/>
<command id="cmd_refresh_list"/>
More information about the open-ils-commits
mailing list