</actions>
</permacrud>
</class>
- <class id="acnc" controller="open-ils.cstore" oils_obj:fieldmapper="asset::call_number_class" oils_persist:tablename="asset.call_number_class" reporter:label="Call number classification scheme">
+ <class id="acnc" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="asset::call_number_class" oils_persist:tablename="asset.call_number_class" reporter:label="Call number classification scheme">
<fields oils_persist:primary="id" oils_persist:sequence="asset.call_number_class_id_seq">
<field reporter:label="Call number class ID" name="id" reporter_datatype="id"/>
<field reporter:label="Name" name="name" reporter:datatype="text"/>
<field reporter:label="Normalizer function" name="normalizer" reporter:datatype="text"/>
<field reporter:label="Call number fields" name="field" reporter:datatype="text"/>
</fields>
+ <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+ <actions>
+ <retrieve/>
+ </actions>
+ </permacrud>
</class>
+ <class id="acns" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="asset::call_number_suffix" oils_persist:tablename="asset.call_number_suffix" reporter:label="Call Number/Volume Suffix">
+ <fields oils_persist:primary="id" oils_persist:sequence="asset.call_number_suffix_id_seq">
+ <field reporter:label="ID" name="id" reporter:datatype="id" />
+ <field reporter:label="Label" name="label" reporter:datatype="text"/>
+ <field reporter:label="Label Sort Key" name="label_sortkey" reporter:datatype="text"/>
+ <field reporter:label="Owning Library" name="owning_lib" reporter:datatype="org_unit"/>
+ </fields>
+ <links>
+ <link field="owning_lib" reltype="has_a" key="id" map="" class="aou"/>
+ </links>
+ <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+ <actions>
+ <create permission="CREATE_VOLUME_SUFFIX" context_field="owning_lib"/>
+ <retrieve/>
+ <update permission="UPDATE_VOLUME_SUFFIX" context_field="owning_lib"/>
+ <delete permission="DELETE_VOLUME_SUFFIX" context_field="owning_lib"/>
+ </actions>
+ </permacrud>
+ </class>
+ <class id="acnp" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="asset::call_number_prefix" oils_persist:tablename="asset.call_number_prefix" reporter:label="Call Number/Volume Prefix">
+ <fields oils_persist:primary="id" oils_persist:sequence="asset.call_number_prefix_id_seq">
+ <field reporter:label="ID" name="id" reporter:datatype="id" />
+ <field reporter:label="Label" name="label" reporter:datatype="text"/>
+ <field reporter:label="Label Sort Key" name="label_sortkey" reporter:datatype="text"/>
+ <field reporter:label="Owning Library" name="owning_lib" reporter:datatype="org_unit"/>
+ </fields>
+ <links>
+ <link field="owning_lib" reltype="has_a" key="id" map="" class="aou"/>
+ </links>
+ <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+ <actions>
+ <create permission="CREATE_VOLUME_PREFIX" context_field="owning_lib"/>
+ <retrieve/>
+ <update permission="UPDATE_VOLUME_PREFIX" context_field="owning_lib"/>
+ <delete permission="DELETE_VOLUME_PREFIX" context_field="owning_lib"/>
+ </actions>
+ </permacrud>
+ </class>
<class id="acn" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="asset::call_number" oils_persist:tablename="asset.call_number" reporter:label="Call Number/Volume">
<fields oils_persist:primary="id" oils_persist:sequence="asset.call_number_id_seq">
<field reporter:label="Copies" name="copies" oils_persist:virtual="true" reporter:datatype="link"/>
<field reporter:label="URIs" name="uris" oils_persist:virtual="true" reporter:datatype="link"/>
<field reporter:label="Sort Key" name="label_sortkey" reporter:datatype="text"/>
<field reporter:label="Classification Scheme" name="label_class" reporter:datatype="link"/>
+ <field reporter:label="Prefix" name="prefix" reporter:datatype="link"/>
+ <field reporter:label="Suffix" name="suffix" reporter:datatype="link"/>
</fields>
<links>
<link field="editor" reltype="has_a" key="id" map="" class="au"/>
<link field="uris" reltype="has_many" key="call_number" map="uri" class="auricnm"/>
<link field="uri_maps" reltype="has_many" key="call_number" map="" class="auricnm"/>
<link field="label_class" reltype="has_a" key="id" map="" class="acnc"/>
+ <link field="prefix" reltype="has_a" key="id" map="" class="acnp"/>
+ <link field="suffix" reltype="has_a" key="id" map="" class="acns"/>
</links>
<permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
<actions>
</actions>
</permacrud>
</class>
+ <class id="bmp" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="biblio::monograph_part" oils_persist:tablename="biblio.monograph_part" reporter:label="Monograph Parts" oils_persist:field_safe="true">
+ <fields oils_persist:primary="id" oils_persist:sequence="biblio.monograph_part_id_seq">
+ <field name="id" reporter:datatype="id" />
+ <field name="record" reporter:datatype="link"/>
+ <field name="label" reporter:datatype="text"/>
+ <field name="label_sortkey" reporter:datatype="text"/>
+ </fields>
+ <links>
+ <link field="record" reltype="has_a" key="id" map="" class="bre"/>
+ </links>
+ <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+ <actions>
+ <create permission="CREATE_MONOGRAPH_PART" global_required="true"/>
+ <retrieve/>
+ <update permission="UPDATE_MONOGRAPH_PART" global_required="true"/>
+ <delete permission="DELETE_MONOGRAPH_PART" global_required="true"/>
+ </actions>
+ </permacrud>
+ </class>
+ <class id="acpm" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="asset::copy_part_map" oils_persist:tablename="asset.copy_part_map" reporter:label="Copy Monograph Part Map">
+ <fields oils_persist:primary="id" oils_persist:sequence="asset.copy_part_map_id_seq">
+ <field name="id" reporter:datatype="id" />
+ <field name="target_copy" reporter:datatype="link" />
+ <field name="part" reporter:datatype="link"/>
+ </fields>
+ <links>
+ <link field="target_copy" reltype="has_a" key="id" map="" class="acp"/>
+ <link field="part" reltype="has_a" key="id" map="" class="bmp"/>
+ </links>
+ <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+ <actions>
+ <create permission="MAP_MONOGRAPH_PART" global_required="true"/>
+ <retrieve/>
+ <update permission="MAP_MONOGRAPH_PART" global_required="true"/>
+ <delete permission="MAP_MONOGRAPH_PART" global_required="true"/>
+ </actions>
+ </permacrud>
+ </class>
<class id="aoucd" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="actor::org_unit::closed_date" oils_persist:tablename="actor.org_unit_closed" reporter:label="Closed Dates">
<fields oils_persist:primary="id" oils_persist:sequence="actor.org_unit_closed_id_seq">
<field name="close_end" reporter:datatype="timestamp" />
<field reporter:label="Total Circulations" name="total_circ_count" oils_persist:virtual="true" reporter:datatype="link"/>
<field reporter:label="Holds" name="holds" oils_persist:virtual="true" reporter:datatype="link"/>
<field reporter:label="Statistical Category Entries" name="stat_cat_entries" oils_persist:virtual="true" reporter:datatype="link"/>
+ <field reporter:label="Monograph Parts" name="parts" oils_persist:virtual="true" reporter:datatype="link"/>
</fields>
<links>
<link field="age_protect" reltype="has_a" key="id" map="" class="crahp"/>
<link field="circulations" reltype="has_many" key="target_copy" map="" class="circ"/>
<link field="total_circ_count" reltype="might_have" key="id" map="" class="erfcc"/>
<link field="circ_modifier" reltype="has_a" key="code" map="" class="ccm"/>
+ <link field="parts" reltype="has_many" key="target_copy" map="part" class="acpm"/>
</links>
<permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
<actions>
}
sub fetch_callnumber {
- my( $self, $id ) = @_;
+ my( $self, $id, $flesh ) = @_;
my $evt = undef;
my $e = OpenILS::Event->new( 'ASSET_CALL_NUMBER_NOT_FOUND', id => $id );
'open-ils.cstore.direct.asset.call_number.retrieve', $id );
$evt = $e unless $cn;
+ if ($flesh && $cn) {
+ $cn->prefix(
+ $self->simplereq(
+ 'open-ils.cstore',
+ 'open-ils.cstore.direct.asset.call_number_prefix.retrieve', $cn->prefix
+ )
+ );
+ $cn->suffix(
+ $self->simplereq(
+ 'open-ils.cstore',
+ 'open-ils.cstore.direct.asset.call_number_suffix.retrieve', $cn->suffix
+ )
+ );
+ $cn->label_class(
+ $self->simplereq(
+ 'open-ils.cstore',
+ 'open-ils.cstore.direct.asset.call_number_class.retrieve', $cn->label_class
+ )
+ );
+ }
+
return ( $cn, $evt );
}
$search_hash->{deleted} = 'f';
my $e = new_editor();
- my $vols = $e->search_asset_call_number([$search_hash, { 'order_by' => {
- 'acn' => 'oils_text_as_bytea(label_sortkey), oils_text_as_bytea(label), id, owning_lib'
- } } ] );
+ my $vols = $e->search_asset_call_number([
+ $search_hash,
+ {
+ flesh => 1,
+ flesh_fields => { acn => ['prefix','suffix','label_class'] },
+ 'order_by' => { 'acn' => 'oils_text_as_bytea(label_sortkey), oils_text_as_bytea(label), id, owning_lib' }
+ }
+ ]);
my @volumes;
for my $volume (@$vols) {
- my $copies = $e->search_asset_copy(
- { call_number => $volume->id , deleted => 'f' });
+ my $copies = $e->search_asset_copy([
+ { call_number => $volume->id , deleted => 'f' },
+ { flesh => 1, flesh_fields => { acp => ['parts'] } }
+ ]);
$copies = [ sort { $a->barcode cmp $b->barcode } @$copies ];
owning_lib => $vol->owning_lib,
record => $vol->record,
label => $vol->label,
+ prefix => $vol->prefix,
+ suffix => $vol->suffix,
deleted => 'f',
id => {'!=' => $vol->id}
});
my $existing_vol = $e->search_asset_call_number(
{
label => $vol->label,
+ prefix => $vol->prefix,
+ suffix => $vol->suffix,
record => $rec,
owning_lib => $o_lib,
deleted => 'f'
);
sub find_or_create_volume {
- my( $self, $conn, $auth, $label, $record_id, $org_id ) = @_;
+ my( $self, $conn, $auth, $label, $record_id, $org_id, $prefix, $suffix, $label_class ) = @_;
my $e = new_editor(authtoken=>$auth, xact=>1);
return $e->die_event unless $e->checkauth;
my ($vol, $evt, $exists) =
- OpenILS::Application::Cat::AssetCommon->find_or_create_volume($e, $label, $record_id, $org_id);
+ OpenILS::Application::Cat::AssetCommon->find_or_create_volume($e, $label, $record_id, $org_id, $prefix, $suffix, $label_class);
return $evt if $evt;
$e->rollback if $exists;
$e->commit if $vol;
- return $vol->id;
+ return { 'acn_id' => $vol->id, 'existed' => $exists };
}
return undef;
}
+# if 'delete_maps' is true, the copy->parts data is treated as the
+# authoritative list for the copy. existing part maps not targeting
+# these parts will be deleted from the DB
+sub update_copy_parts {
+ my($class, $editor, $copy, $delete_maps) = @_;
+
+ return undef if $copy->isdeleted;
+ return undef unless $copy->ischanged or $copy->isnew;
+
+ my $evt;
+ my $incoming_parts = $copy->parts;
+
+ if( $delete_maps ) {
+ $incoming_parts = ($incoming_parts and @$incoming_parts) ? $incoming_parts : [];
+ } else {
+ return undef unless ($incoming_parts and @$incoming_parts);
+ }
+
+ my $maps = $editor->search_asset_copy_part_map({target_copy=>$copy->id});
+
+ if(!$copy->isnew) {
+ # if there is no part map on the copy who's id matches the
+ # current map's id, remove the map from the database
+ for my $map (@$maps) {
+ if(! grep { $_->id == $map->part } @$incoming_parts ) {
+
+ $logger->info("copy update found stale ".
+ "monographic part map ".$map->id. " on copy ".$copy->id);
+
+ $editor->delete_asset_copy_part_map($map)
+ or return $editor->event;
+ }
+ }
+ }
+
+ # go through the part map update/create process
+ for my $incoming_part (@$incoming_parts) {
+ next unless $incoming_part;
+
+ # if this link already exists in the DB, don't attempt to re-create it
+ next if( grep{$_->part == $incoming_part->id} @$maps );
+
+ my $new_map = Fieldmapper::asset::copy_part_map->new();
+
+ $new_map->part( $incoming_part->id );
+ $new_map->target_copy( $copy->id );
+
+ $editor->create_asset_copy_part_map($new_map)
+ or return $editor->event;
+
+ $logger->info("copy update created new monographic part copy map ".$editor->data);
+ }
+
+ return undef;
+}
+
+
sub update_copy {
my($class, $editor, $override, $vol, $copy, $retarget_holds, $force_delete_empty_bib) = @_;
my $sc_entries = $copy->stat_cat_entries;
$copy->clear_stat_cat_entries;
+ my $parts = $copy->parts;
+ $copy->clear_parts;
+
if( $copy->isdeleted ) {
$evt = $class->delete_copy($editor, $override, $vol, $copy, $retarget_holds, $force_delete_empty_bib);
return $evt if $evt;
$copy->stat_cat_entries( $sc_entries );
$evt = $class->update_copy_stat_entries($editor, $copy, $delete_stats);
+ $copy->parts( $parts );
+ # probably okay to use $delete_stats here for simplicity
+ $evt = $class->update_copy_parts($editor, $copy, $delete_stats);
return $evt if $evt;
}
owning_lib => $vol->owning_lib,
record => $vol->record,
label => $vol->label,
+ prefix => $vol->prefix,
+ suffix => $vol->suffix,
deleted => 'f'
}
);
# returns the volume if it exists
sub volume_exists {
- my($class, $e, $rec_id, $label, $owning_lib) = @_;
+ my($class, $e, $rec_id, $label, $owning_lib, $prefix, $suffix) = @_;
return $e->search_asset_call_number(
- {label => $label, record => $rec_id, owning_lib => $owning_lib, deleted => 'f'})->[0];
+ {label => $label, record => $rec_id, owning_lib => $owning_lib, deleted => 'f', prefix => $prefix, suffix => $suffix})->[0];
}
sub find_or_create_volume {
- my($class, $e, $label, $record_id, $org_id) = @_;
+ my($class, $e, $label, $record_id, $org_id, $prefix, $suffix, $label_class) = @_;
+
+ $prefix ||= '-1';
+ $suffix ||= '-1';
my $vol;
or return (undef, $e->die_event);
} else {
- $vol = $class->volume_exists($e, $record_id, $label, $org_id);
+ $vol = $class->volume_exists($e, $record_id, $label, $org_id, $prefix, $suffix);
}
# If the volume exists, return the ID
$vol = Fieldmapper::asset::call_number->new;
$vol->owning_lib($org_id);
+ $vol->label_class($label_class) if ($label_class);
$vol->label($label);
+ $vol->prefix($prefix);
+ $vol->suffix($suffix);
$vol->record($record_id);
my $evt = OpenILS::Application::Cat::AssetCommon->create_volume(0, $e, $vol);
{
flesh => 2,
flesh_fields => {
- acp => ['call_number'],
- acn => ['record']
+ acp => ['call_number','parts'],
+ acn => ['record','prefix','suffix','label_class']
}
}
]) or return $e->event;
return $e->die_event unless $e->allowed('TITLE_HOLDS', $porg);
} elsif ( $t eq OILS_HOLD_TYPE_VOLUME ) {
return $e->die_event unless $e->allowed('VOLUME_HOLDS', $porg);
+ } elsif ( $t eq OILS_HOLD_TYPE_MONOPART ) {
+ return $e->die_event unless $e->allowed('TITLE_HOLDS', $porg);
} elsif ( $t eq OILS_HOLD_TYPE_ISSUANCE ) {
return $e->die_event unless $e->allowed('ISSUANCE_HOLDS', $porg);
} elsif ( $t eq OILS_HOLD_TYPE_COPY ) {
pickup_lib - destination for hold, fallback value for selection_ou
selection_ou - ID of org_unit establishing hard and soft hold boundary settings
issuanceid - ID of the issuance to be held, required for Issuance level hold
+ partid - ID of the monograph part to be held, required for monograph part level hold
titleid - ID (BRN) of the title to be held, required for Title level hold
volume_id - required for Volume level hold
copy_id - required for Copy level hold
my($e, $patron, $request_lib, $depth, %params) = @_;
my $issuanceid = $params{issuanceid} || "";
+ my $partid = $params{partid} || "";
my $titleid = $params{titleid} || "";
my $volid = $params{volume_id};
my $copyid = $params{copy_id};
$issuanceid, $depth, $request_lib, $patron, $e->requestor, $pickup_lib, $selection_ou
);
+ } elsif( $hold_type eq OILS_HOLD_TYPE_MONOPART ) {
+
+ return _check_monopart_hold_is_possible(
+ $partid, $depth, $request_lib, $patron, $e->requestor, $pickup_lib, $selection_ou
+ );
+
} elsif( $hold_type eq OILS_HOLD_TYPE_METARECORD ) {
my $maps = $e->search_metabib_metarecord_source_map({metarecord=>$mrid});
return @status;
}
+sub _check_monopart_hold_is_possible {
+ my( $partid, $depth, $request_lib, $patron, $requestor, $pickup_lib, $selection_ou ) = @_;
+
+ my $e = new_editor();
+ my %org_filter = create_ranged_org_filter($e, $selection_ou, $depth);
+
+ # this monster will grab the id and circ_lib of all of the "holdable" copies for the given record
+ my $copies = $e->json_query(
+ {
+ select => { acp => ['id', 'circ_lib'] },
+ from => {
+ acp => {
+ acpm => {
+ field => 'target_copy',
+ fkey => 'id',
+ filter => { part => $partid }
+ },
+ acpl => { field => 'id', filter => { holdable => 't'}, fkey => 'location' },
+ ccs => { field => 'id', filter => { holdable => 't'}, fkey => 'status' }
+ }
+ },
+ where => {
+ '+acp' => { circulate => 't', deleted => 'f', holdable => 't', %org_filter }
+ },
+ distinct => 1
+ }
+ );
+
+ $logger->info("monopart possible found ".scalar(@$copies)." potential copies");
+
+ my $empty_ok;
+ if (!@$copies) {
+ $empty_ok = $e->retrieve_config_global_flag('circ.holds.empty_part_ok');
+ $empty_ok = ($empty_ok and $U->is_true($empty_ok->enabled));
+
+ return (
+ 0, 0, [
+ new OpenILS::Event(
+ "HIGH_LEVEL_HOLD_HAS_NO_COPIES",
+ "payload" => {"fail_part" => "no_ultimate_items"}
+ )
+ ]
+ ) unless $empty_ok;
+
+ return (1, 0);
+ }
+
+ # -----------------------------------------------------------------------
+ # sort the copies into buckets based on their circ_lib proximity to
+ # the patron's home_ou.
+ # -----------------------------------------------------------------------
+
+ my $home_org = $patron->home_ou;
+ my $req_org = $request_lib->id;
+
+ $logger->info("prox cache $home_org " . $prox_cache{$home_org});
+
+ $prox_cache{$home_org} =
+ $e->search_actor_org_unit_proximity({from_org => $home_org})
+ unless $prox_cache{$home_org};
+ my $home_prox = $prox_cache{$home_org};
+
+ my %buckets;
+ my %hash = map { ($_->to_org => $_->prox) } @$home_prox;
+ push( @{$buckets{ $hash{$_->{circ_lib}} } }, $_->{id} ) for @$copies;
+
+ my @keys = sort { $a <=> $b } keys %buckets;
+
+
+ if( $home_org ne $req_org ) {
+ # -----------------------------------------------------------------------
+ # shove the copies close to the request_lib into the primary buckets
+ # directly before the farthest away copies. That way, they are not
+ # given priority, but they are checked before the farthest copies.
+ # -----------------------------------------------------------------------
+ $prox_cache{$req_org} =
+ $e->search_actor_org_unit_proximity({from_org => $req_org})
+ unless $prox_cache{$req_org};
+ my $req_prox = $prox_cache{$req_org};
+
+ my %buckets2;
+ my %hash2 = map { ($_->to_org => $_->prox) } @$req_prox;
+ push( @{$buckets2{ $hash2{$_->{circ_lib}} } }, $_->{id} ) for @$copies;
+
+ my $highest_key = $keys[@keys - 1]; # the farthest prox in the exising buckets
+ my $new_key = $highest_key - 0.5; # right before the farthest prox
+ my @keys2 = sort { $a <=> $b } keys %buckets2;
+ for my $key (@keys2) {
+ last if $key >= $highest_key;
+ push( @{$buckets{$new_key}}, $_ ) for @{$buckets2{$key}};
+ }
+ }
+
+ @keys = sort { $a <=> $b } keys %buckets;
+
+ my $title;
+ my %seen;
+ my @status;
+ OUTER: for my $key (@keys) {
+ my @cps = @{$buckets{$key}};
+
+ $logger->info("looking at " . scalar(@{$buckets{$key}}). " copies in proximity bucket $key");
+
+ for my $copyid (@cps) {
+
+ next if $seen{$copyid};
+ $seen{$copyid} = 1; # there could be dupes given the merged buckets
+ my $copy = $e->retrieve_asset_copy($copyid);
+ $logger->debug("looking at bucket_key=$key, copy $copyid : circ_lib = " . $copy->circ_lib);
+
+ unless($title) { # grab the title if we don't already have it
+ my $vol = $e->retrieve_asset_call_number(
+ [ $copy->call_number, { flesh => 1, flesh_fields => { bre => ['fixed_fields'], acn => ['record'] } } ] );
+ $title = $vol->record;
+ }
+
+ @status = verify_copy_for_hold(
+ $patron, $requestor, $title, $copy, $pickup_lib, $request_lib);
+
+ last OUTER if $status[0];
+ }
+ }
+
+ if (!$status[0]) {
+ if (!defined($empty_ok)) {
+ $empty_ok = $e->retrieve_config_global_flag('circ.holds.empty_part_ok');
+ $empty_ok = ($empty_ok and $U->is_true($empty_ok->enabled));
+ }
+
+ return (1,0) if ($empty_ok);
+ }
+ return @status;
+}
+
sub _check_volume_hold_is_possible {
my( $vol, $title, $depth, $request_lib, $patron, $requestor, $pickup_lib, $selection_ou ) = @_;
$hold->usr($user->id);
- my( $mvr, $volume, $copy, $issuance, $bre ) = find_hold_mvr($e, $hold, $args->{suppress_mvr});
+ my( $mvr, $volume, $copy, $issuance, $part, $bre ) = find_hold_mvr($e, $hold, $args->{suppress_mvr});
flesh_hold_notices([$hold], $e) unless $args->{suppress_notices};
flesh_hold_transits([$hold]) unless $args->{suppress_transits};
my $resp = {
hold => $hold,
- copy => $copy,
- volume => $volume,
+ ($copy ? (copy => $copy) : ()),
+ ($volume ? (volume => $volume) : ()),
+ ($issuance ? (issuance => $issuance) : ()),
+ ($part ? (part => $part) : ()),
+ ($args->{include_bre} ? (bre => $bre) : ()),
+ ($args->{suppress_mvr} ? () : (mvr => $mvr)),
%$details
};
- $resp->{mvr} = $mvr unless $args->{suppress_mvr};
unless($args->{suppress_patron_details}) {
my $card = $e->retrieve_actor_card($user->card) or return $e->event;
$resp->{patron_first} = $user->first_given_name,
$resp->{patron_alias} = $user->alias,
};
- $resp->{bre} = $bre if $args->{include_bre};
-
return $resp;
}
my $copy;
my $volume;
my $issuance;
+ my $part;
if( $hold->hold_type eq OILS_HOLD_TYPE_METARECORD ) {
my $mr = $e->retrieve_metabib_metarecord($hold->target)
$tid = $issuance->subscription->record_entry;
+ } elsif( $hold->hold_type eq OILS_HOLD_TYPE_MONOPART ) {
+ $part = $e->retrieve_biblio_monographic_part([
+ $hold->target,
+ {flesh => 1, flesh_fields => {bmp => [ qw/record/ ]}}
+ ]) or return $e->event;
+
+ $tid = $part->record;
+
} elsif( $hold->hold_type eq OILS_HOLD_TYPE_COPY ) {
$copy = $e->retrieve_asset_copy([
$hold->target,
# TODO return metarcord mvr for M holds
my $title = $e->retrieve_biblio_record_entry($tid);
- return ( ($no_mvr) ? undef : $U->record_to_mvr($title), $volume, $copy, $issuance, $title );
+ return ( ($no_mvr) ? undef : $U->record_to_mvr($title), $volume, $copy, $issuance, $part, $title );
}
__PACKAGE__->register_method(
$query->{where}->{'+acp'}->{call_number} = $hold_target;
+ } elsif($hold_type eq 'P') {
+
+ $query->{from}->{acp}->{acpm} = {
+ field => 'target_copy',
+ fkey => 'id',
+ filter => {part => $hold_target},
+ };
+
} elsif($hold_type eq 'I') {
$query->{from}->{acp}->{sitem} = {
'-or' => [
{
'-and' => {
- hold_type => 'C',
+ hold_type => [qw/C F R/],
target => {
in => {
select => {acp => ['id']},
"open-ils.cstore.direct.asset.copy.search.atomic",
{ id => $ids },
{ flesh => 1,
- flesh_fields => { acp => [ qw/ circ_lib location status stat_cat_entries / ] }
+ flesh_fields => { acp => [ qw/ circ_lib location status stat_cat_entries parts / ] }
});
}
flesh => 2,
flesh_fields => {
acp => [
- qw/ location status stat_cat_entry_copy_maps notes age_protect /
+ qw/ location status stat_cat_entry_copy_maps notes age_protect parts /
],
ascecm => [qw/ stat_cat stat_cat_entry /],
}
}
__PACKAGE__->register_method(
+ method => "fetch_fleshed_cn",
+ api_name => "open-ils.search.callnumber.fleshed.retrieve",
+ authoritative => 1,
+ notes => "retrieves a callnumber based on ID, fleshing prefix, suffix, and label_class",
+);
+
+sub fetch_fleshed_cn {
+ my( $self, $client, $id ) = @_;
+ my( $cn, $evt ) = $apputils->fetch_callnumber( $id, 1 );
+ return $evt if $evt;
+ return $cn;
+}
+
+
+__PACKAGE__->register_method(
method => "fetch_copy_by_cn",
api_name => 'open-ils.search.copies_by_call_number.retrieve',
signature => q/
return \@res;
}
+__PACKAGE__->register_method(
+ method => 'rec_hold_parts',
+ api_name => 'open-ils.search.biblio.record_hold_parts',
+ signature => q/
+ Returns a list of {label :foo, id : bar} objects for viable monograph parts for a given record
+ /
+);
+
+sub rec_hold_parts {
+ my( $self, $conn, $args ) = @_;
+
+ my $rec = $$args{record};
+ my $mrec = $$args{metarecord};
+ my $pickup_lib = $$args{pickup_lib};
+ my $e = new_editor();
+
+ my $query = {
+ select => {bmp => ['id', 'label']},
+ from => 'bmp',
+ where => {
+ id => {
+ in => {
+ select => {'acpm' => ['part']},
+ from => {acpm => {acp => {join => {acn => {join => 'bre'}}}}},
+ where => {
+ '+acp' => {'deleted' => 'f'},
+ '+bre' => {id => $rec}
+ },
+ distinct => 1,
+ }
+ }
+ }
+ };
+
+ if(defined $pickup_lib) {
+ my $hard_boundary = $U->ou_ancestor_setting_value($pickup_lib, OILS_SETTING_HOLD_HARD_BOUNDARY);
+ if($hard_boundary) {
+ my $orgs = $e->json_query({from => ['actor.org_unit_descendants' => $pickup_lib, $hard_boundary]});
+ $query->{where}->{'+acp'}->{circ_lib} = [ map { $_->{id} } @$orgs ];
+ }
+ }
+
+ return $e->json_query($query);
+}
+
+
__PACKAGE__->register_method(
sub _find_or_create_call_number {
my ($e, $lib, $cn_string, $record) = @_;
+ # FIXME: should suffix and prefix come into play here?
my $existing = $e->search_asset_call_number({
"owning_lib" => $lib,
"label" => $cn_string,
asset::call_number->has_many( copies => 'asset::copy' );
asset::call_number->has_many( notes => 'asset::call_number_note' );
+ asset::call_number->has_a( prefix => 'asset::call_number_prefix' );
+ asset::call_number->has_a( suffix => 'asset::call_number_suffix' );
+
+ asset::call_number_prefix->has_a( owning_lib => 'actor::org_unit' );
+ asset::call_number_suffix->has_a( owning_lib => 'actor::org_unit' );
+
+ asset::call_number_prefix->has_many( call_numbers => 'asset::call_number' );
+ asset::call_number_suffix->has_many( call_numbers => 'asset::call_number' );
+
authority::record_entry->has_many( record_descriptor => 'authority::record_descriptor' );
authority::record_entry->has_many( notes => 'authority::record_note' );
__PACKAGE__->columns( Essential => qw/location org position/ );
#-------------------------------------------------------------------------------
+package asset::call_number_suffix;
+use base qw/asset/;
+
+__PACKAGE__->table( 'asset_call_number_suffix' );
+__PACKAGE__->columns( Primary => qw/id/ );
+__PACKAGE__->columns( Essential => qw/owning_lib label label_sortkey/ );
+
+#-------------------------------------------------------------------------------
+package asset::call_number_prefix;
+use base qw/asset/;
+
+__PACKAGE__->table( 'asset_call_number_prefix' );
+__PACKAGE__->columns( Primary => qw/id/ );
+__PACKAGE__->columns( Essential => qw/owning_lib label label_sortkey/ );
+
+#-------------------------------------------------------------------------------
package asset::call_number_class;
use base qw/asset/;
__PACKAGE__->table( 'asset_call_number' );
__PACKAGE__->columns( Primary => qw/id/ );
-__PACKAGE__->columns( Essential => qw/record label creator create_date editor
+__PACKAGE__->columns( Essential => qw/record label creator create_date editor prefix suffix
edit_date record label owning_lib deleted label_class label_sortkey/ );
#-------------------------------------------------------------------------------
age_protect floating cost status_changed_time/ );
#-------------------------------------------------------------------------------
+package asset::copy_part_map;
+use base qw/asset/;
+
+__PACKAGE__->table( 'asset_copy_part_map' );
+__PACKAGE__->columns( Primary => qw/id/ );
+__PACKAGE__->columns( Essential => qw/target_copy part/);
+
+#-------------------------------------------------------------------------------
package asset::stat_cat;
use base qw/asset/;
editor create_date edit_date pub/ );
#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
+package biblio::monograph_part;
+use base qw/biblio/;
+
+biblio::monograph_part->table( 'biblio_monograph_part' );
+biblio::monograph_part->columns( Essential => qw/id record label label_sortkey/ );
+#-------------------------------------------------------------------------------
+
1;
{
+ #-------------------------------------------------------------------------------
+ package asset::copy_part_map;
+
+ asset::copy_part_map->table( 'asset.copy_part_map' );
+
+ #-------------------------------------------------------------------------------
+ package biblio::monograph_part;
+
+ biblio::monograph_part->table( 'biblio.monograph_part' );
+ biblio::monograph_part->sequence( 'biblio.monograph_part_id_seq' );
+
#-------------------------------------------------------------------------------
package container::user_bucket;
asset::call_number->sequence( 'asset.call_number_id_seq' );
#---------------------------------------------------------------------
+ package asset::call_number_suffix;
+
+ asset::call_number_suffix->table( 'asset.call_number_suffix' );
+ asset::call_number_suffix->sequence( 'asset.call_number_suffix_id_seq' );
+
+ #---------------------------------------------------------------------
+ package asset::call_number_prefix;
+
+ asset::call_number_prefix->table( 'asset.call_number_prefix' );
+ asset::call_number_prefix->sequence( 'asset.call_number_prefix_id_seq' );
+
+ #---------------------------------------------------------------------
package asset::call_number_class;
asset::call_number_class->table( 'asset.call_number_class' );
{ id => [map {$_->id} @{ $vtree->copies }],
deleted => 'f' }
) if ($vtree && @{ $vtree->copies });
+
+ } elsif ($hold->hold_type eq 'P') {
+ my @part_maps = asset::copy_part_map->search_where( { part => $hold->target } );
+ $all_copies = [
+ asset::copy->search_where(
+ { id => [map {$_->target_copy} @part_maps],
+ deleted => 'f' }
+ )
+ ] if (@part_maps);
} elsif ($hold->hold_type eq 'I') {
my ($itree) = $self
my $descendants = "actor.org_unit_descendants(?,?)";
my $cn_table = asset::call_number->table;
+ my $cnp_table = asset::call_number_prefix->table;
+ my $cns_table = asset::call_number_prefix->table;
my $cp_table = asset::copy->table;
my $cl_table = asset::copy_location->table;
my $cs_table = config::copy_status->table;
my $sql = <<" SQL";
- SELECT cp.circ_lib, cn.label, cp.status, count(cp.id)
+ SELECT cp.circ_lib,
+ CASE WHEN cnp.id > -1 THEN cnp.label || ' ' ELSE '' END || cn.label || CASE WHEN cns.id > -1 THEN ' ' || cns.label ELSE '' END,
+ cp.status,
+ count(cp.id)
FROM $cp_table cp,
$cn_table cn,
+ $cns_table cns,
+ $cnp_table cnp,
$cl_table cl,
$cs_table cs,
$descendants d
WHERE cn.record = ?
+ AND cnp.id = cn.prefix
+ AND cns.id = cn.suffix
AND cp.call_number = cn.id
AND cp.location = cl.id
AND cp.circ_lib = d.id
my $descendants = "actor.org_unit_descendants(?,?)";
my $cn_table = asset::call_number->table;
+ my $cnp_table = asset::call_number_prefix->table;
+ my $cns_table = asset::call_number_prefix->table;
my $cp_table = asset::copy->table;
my $cl_table = asset::copy_location->table;
my $cs_table = config::copy_status->table;
my $sql = <<" SQL";
SELECT cp.circ_lib,
- cn.label,
+ CASE WHEN cnp.id > -1 THEN cnp.label || ' ' ELSE '' END || cn.label || CASE WHEN cns.id > -1 THEN ' ' || cns.label ELSE '' END,
oils_i18n_xlate('asset.copy_location', 'acpl', 'name', 'id', cl.id::TEXT, ?),
cp.status,
count(cp.id)
FROM $cp_table cp,
$cn_table cn,
+ $cns_table cns,
+ $cnp_table cnp,
$cl_table cl,
$cs_table cs,
$descendants d
WHERE cn.record = ?
+ AND cnp.id = cn.prefix
+ AND cns.id = cn.suffix
AND cp.call_number = cn.id
AND cp.location = cl.id
AND cp.circ_lib = d.id
@cp_filter
},
{ flesh => 1,
- flesh_fields => { acn => [qw/record owning_lib/] },
+ flesh_fields => { acn => [qw/record owning_lib prefix suffix/] },
order_by => { acn => "oils_text_as_bytea(label_sortkey) desc, oils_text_as_bytea(label) desc, id desc, owning_lib desc" },
limit => $before_limit,
offset => abs($page) * $page_size - $before_offset,
@cp_filter
},
{ flesh => 1,
- flesh_fields => { acn => [qw/record owning_lib/] },
+ flesh_fields => { acn => [qw/record owning_lib prefix suffix/] },
order_by => { acn => "oils_text_as_bytea(label_sortkey), oils_text_as_bytea(label), id, owning_lib" },
limit => $after_limit,
offset => abs($page) * $page_size - $after_offset,
@cp_filter
},
{ flesh => 1,
- flesh_fields => { acn => [qw/record owning_lib/] },
+ flesh_fields => { acn => [qw/record owning_lib prefix suffix/] },
order_by => { acn => "oils_text_as_bytea(label_sortkey) desc, oils_text_as_bytea(label) desc, id desc, owning_lib desc" },
limit => $limit,
offset => $offset,
@cp_filter
},
{ flesh => 1,
- flesh_fields => { acn => [qw/record owning_lib/] },
+ flesh_fields => { acn => [qw/record owning_lib prefix suffix/] },
order_by => { acn => "oils_text_as_bytea(label_sortkey), oils_text_as_bytea(label), id, owning_lib" },
limit => $limit,
offset => $offset,
flesh_fields => {
auri => [qw/call_number_maps/],
auricnm => [qw/call_number/],
- acn => [qw/owning_lib record/],
+ acn => [qw/owning_lib record prefix suffix/],
}
})
->gather(1))
$cpid,
{ flesh => 2,
flesh_fields => {
- acn => [qw/owning_lib record/],
- acp => [qw/call_number location status circ_lib stat_cat_entries notes/],
+ acn => [qw/owning_lib record prefix suffix/],
+ acp => [qw/call_number location status circ_lib stat_cat_entries notes parts/],
}
})
->gather(1))
$cnid,
{ flesh => 5,
flesh_fields => {
- acn => [qw/owning_lib record copies uri_maps/],
+ acn => [qw/owning_lib record copies uri_maps prefix suffix/],
auricnm => [qw/uri/],
- acp => [qw/location status circ_lib stat_cat_entries notes/],
+ acp => [qw/location status circ_lib stat_cat_entries notes parts/],
}
})
->gather(1))
{ flesh => 5,
flesh_fields => {
bre => [qw/call_numbers/],
- acn => [qw/copies owning_lib/],
- acp => [qw/location status circ_lib/],
+ acn => [qw/copies owning_lib prefix suffix/],
+ acp => [qw/location status circ_lib parts/],
}
}
)->gather(1);
},
{ flesh => 5,
flesh_fields => {
- acn => [qw/copies owning_lib uri_maps/],
+ acn => [qw/copies owning_lib uri_maps prefix suffix/],
auricnm => [qw/uri/],
- acp => [qw/circ_lib location status stat_cat_entries notes/],
+ acp => [qw/circ_lib location status stat_cat_entries notes parts/],
asce => [qw/stat_cat/],
},
( $limit > -1 ? ( limit => $limit ) : () ),
sstr => [qw/items/],
sitem => [qw/notes unit/],
sunit => [qw/notes location status circ_lib stat_cat_entries call_number/],
- acn => [qw/owning_lib/],
+ acn => [qw/owning_lib prefix suffix/],
},
( $limit > -1 ? ( limit => $limit ) : () ),
( $offset ? ( offset => $offset ) : () ),
}
+ $xml .= ' <prefix ';
+ $xml .= 'ident="' . $self->obj->prefix->id . '" ';
+ $xml .= 'id="tag:open-ils.org:asset-call_number_prefix/' . $self->obj->prefix->id . '" ';
+ $xml .= 'label_sortkey="'.$self->escape( $self->obj->prefix->label_sortkey ) .'">';
+ $xml .= $self->escape( $self->obj->prefix->label ) .'</prefix>';
+ $xml .= "\n";
+
+ $xml .= ' <suffix ';
+ $xml .= 'ident="' . $self->obj->suffix->id . '" ';
+ $xml .= 'id="tag:open-ils.org:asset-call_number_suffix/' . $self->obj->suffix->id . '" ';
+ $xml .= 'label_sortkey="'.$self->escape( $self->obj->suffix->label_sortkey ) .'">';
+ $xml .= $self->escape( $self->obj->suffix->label ) .'</suffix>';
+ $xml .= "\n";
+
$xml .= ' <owning_lib xmlns="http://open-ils.org/spec/actors/v1" ';
$xml .= 'id="tag:open-ils.org:actor-org_unit/' . $self->obj->owning_lib->id . '" ';
$xml .= 'shortname="'.$self->escape( $self->obj->owning_lib->shortname ) .'" ';
$xml .= 'name="'.$self->escape( $self->obj->circ_lib->name ) .'" opac_visible="'.$self->obj->circ_lib->opac_visible.'"/>';
$xml .= "\n";
+ $xml .= " <monograph_parts>\n";
+ if (ref($self->obj->parts) && $self->obj->parts) {
+ for my $part ( @{$self->obj->parts} ) {
+ $xml .= sprintf(' <monograph_part record="%s" sortkey="%s">%s</monograph_part>',$part->record, $self->escape($part->label_sortkey), $self->escape($part->label));
+ $xml .= "\n";
+ }
+ }
+
+ $xml .= " </monograph_parts>\n";
$xml .= " <copy_notes>\n";
if (ref($self->obj->notes) && $self->obj->notes) {
for my $note ( @{$self->obj->notes} ) {
econst OILS_HOLD_TYPE_VOLUME => 'V';
econst OILS_HOLD_TYPE_TITLE => 'T';
econst OILS_HOLD_TYPE_METARECORD => 'M';
+econst OILS_HOLD_TYPE_MONOPART => 'P';
econst OILS_BILLING_TYPE_OVERDUE_MATERIALS => 'Overdue materials';
install_date TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);
-INSERT INTO config.upgrade_log (version) VALUES ('0503'); -- miker for tsbere
+INSERT INTO config.upgrade_log (version) VALUES ('0504'); -- miker for tsbere
CREATE TABLE config.bib_source (
id SERIAL PRIMARY KEY,
CREATE INDEX biblio_record_note_creator_idx ON biblio.record_note ( creator );
CREATE INDEX biblio_record_note_editor_idx ON biblio.record_note ( editor );
+CREATE TABLE biblio.monograph_part (
+ id SERIAL PRIMARY KEY,
+ record BIGINT NOT NULL REFERENCES biblio.record_entry (id),
+ label TEXT NOT NULL,
+ label_sortkey TEXT NOT NULL,
+ CONSTRAINT record_label_unique UNIQUE (record,label)
+);
+
+CREATE OR REPLACE FUNCTION biblio.normalize_biblio_monograph_part_sortkey () RETURNS TRIGGER AS $$
+BEGIN
+ NEW.label_sortkey := REGEXP_REPLACE(
+ lpad_number_substrings(
+ naco_normalize(NEW.label),
+ '0',
+ 10
+ ),
+ E'\\s+',
+ '',
+ 'g'
+ );
+ RETURN NEW;
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE TRIGGER norm_sort_label BEFORE INSERT OR UPDATE ON biblio.monograph_part FOR EACH ROW EXECUTE PROCEDURE biblio.normalize_biblio_monograph_part_sortkey();
+
COMMIT;
CREATE INDEX cp_create_date ON asset.copy (create_date);
CREATE RULE protect_copy_delete AS ON DELETE TO asset.copy DO INSTEAD UPDATE asset.copy SET deleted = TRUE WHERE OLD.id = asset.copy.id;
+CREATE TABLE asset.copy_part_map (
+ id SERIAL PRIMARY KEY,
+ target_copy BIGINT NOT NULL, -- points o asset.copy
+ part INT NOT NULL REFERENCES biblio.monograph_part (id) ON DELETE CASCADE
+);
+CREATE UNIQUE INDEX copy_part_map_cp_part_idx ON asset.copy_part_map (target_copy, part);
+
CREATE TABLE asset.opac_visible_copies (
id BIGINT primary key, -- copy id
record BIGINT,
('Library of Congress (LC)', 'asset.label_normalizer_lc', '050ab,055ab,090abef')
;
+CREATE OR REPLACE FUNCTION asset.normalize_affix_sortkey () RETURNS TRIGGER AS $$
+BEGIN
+ NEW.label_sortkey := REGEXP_REPLACE(
+ lpad_number_substrings(
+ naco_normalize(NEW.label),
+ '0',
+ 10
+ ),
+ E'\\s+',
+ '',
+ 'g'
+ );
+ RETURN NEW;
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE TABLE asset.call_number_prefix (
+ id SERIAL PRIMARY KEY,
+ owning_lib INT NOT NULL REFERENCES actor.org_unit (id),
+ label TEXT NOT NULL, -- i18n
+ label_sortkey TEXT
+);
+CREATE TRIGGER prefix_normalize_tgr BEFORE INSERT OR UPDATE ON asset.call_number_prefix FOR EACH ROW EXECUTE PROCEDURE asset.normalize_affix_sortkey();
+CREATE UNIQUE INDEX asset_call_number_prefix_once_per_lib ON asset.call_number_prefix (label, owning_lib);
+CREATE INDEX asset_call_number_prefix_sortkey_idx ON asset.call_number_prefix (label_sortkey);
+
+CREATE TABLE asset.call_number_suffix (
+ id SERIAL PRIMARY KEY,
+ owning_lib INT NOT NULL REFERENCES actor.org_unit (id),
+ label TEXT NOT NULL, -- i18n
+ label_sortkey TEXT
+);
+CREATE TRIGGER suffix_normalize_tgr BEFORE INSERT OR UPDATE ON asset.call_number_suffix FOR EACH ROW EXECUTE PROCEDURE asset.normalize_affix_sortkey();
+CREATE UNIQUE INDEX asset_call_number_suffix_once_per_lib ON asset.call_number_suffix (label, owning_lib);
+CREATE INDEX asset_call_number_suffix_sortkey_idx ON asset.call_number_suffix (label_sortkey);
+
CREATE TABLE asset.call_number (
id bigserial PRIMARY KEY,
creator BIGINT NOT NULL,
editor BIGINT NOT NULL,
edit_date TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
record bigint NOT NULL,
- owning_lib INT NOT NULL,
+ owning_lib INT NOT NULL,
label TEXT NOT NULL,
deleted BOOL NOT NULL DEFAULT FALSE,
+ prefix INT NOT NULL DEFAULT -1 REFERENCES asset.call_number_prefix(id) DEFERRABLE INITIALLY DEFERRED,
+ suffix INT NOT NULL DEFAULT -1 REFERENCES asset.call_number_suffix(id) DEFERRABLE INITIALLY DEFERRED,
label_class BIGINT DEFAULT 1 NOT NULL
REFERENCES asset.call_number_class(id)
DEFERRABLE INITIALLY DEFERRED,
CREATE INDEX asset_call_number_dewey_idx ON asset.call_number (public.call_number_dewey(label));
CREATE INDEX asset_call_number_upper_label_id_owning_lib_idx ON asset.call_number (oils_text_as_bytea(label),id,owning_lib);
CREATE INDEX asset_call_number_label_sortkey ON asset.call_number(oils_text_as_bytea(label_sortkey));
-CREATE UNIQUE INDEX asset_call_number_label_once_per_lib ON asset.call_number (record, owning_lib, label) WHERE deleted = FALSE OR deleted IS FALSE;
+CREATE UNIQUE INDEX asset_call_number_label_once_per_lib ON asset.call_number (record, owning_lib, label, prefix, suffix) WHERE deleted = FALSE OR deleted IS FALSE;
CREATE INDEX asset_call_number_label_sortkey_browse ON asset.call_number(oils_text_as_bytea(label_sortkey), oils_text_as_bytea(label), id, owning_lib) WHERE deleted IS FALSE OR deleted = FALSE;
CREATE RULE protect_cn_delete AS ON DELETE TO asset.call_number DO INSTEAD UPDATE asset.call_number SET deleted = TRUE WHERE OLD.id = asset.call_number.id;
CREATE TRIGGER asset_label_sortkey_trigger
INSERT INTO asset.copy_location (id, name,owning_lib) VALUES (1, oils_i18n_gettext(1, 'Stacks', 'acpl', 'name'),1);
SELECT SETVAL('asset.copy_location_id_seq'::TEXT, 100);
+INSERT INTO asset.call_number_suffix (id, owning_lib, label) VALUES (-1, 1, '');
+INSERT INTO asset.call_number_prefix (id, owning_lib, label) VALUES (-1, 1, '');
INSERT INTO asset.call_number VALUES (-1,1,NOW(),1,NOW(),-1,1,'UNCATALOGED');
-- circ matrix
(37, 'circ_lib.billing_address')
;
+INSERT INTO config.org_unit_setting_type ( name, label, description, datatype ) VALUES (
+ 'ui.cat.volume_copy_editor.horizontal',
+ oils_i18n_gettext(
+ 'ui.cat.volume_copy_editor.horizontal',
+ 'GUI: Horizontal layout for Volume/Copy Creator/Editor.',
+ 'coust', 'label'),
+ oils_i18n_gettext(
+ 'ui.cat.volume_copy_editor.horizontal',
+ 'The main entry point for this interface is in Holdings Maintenance, Actions for Selected Rows, Edit Item Attributes / Call Numbers / Replace Barcodes. This setting changes the top and bottom panes for that interface into left and right panes.',
+ 'coust', 'description'),
+ 'bool'
+);
-- Dummy functions, so we can create the real ones out of order
CREATE OR REPLACE FUNCTION unapi.aou ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
+CREATE OR REPLACE FUNCTION unapi.acnp ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
+CREATE OR REPLACE FUNCTION unapi.acns ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
CREATE OR REPLACE FUNCTION unapi.acn ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
CREATE OR REPLACE FUNCTION unapi.ssub ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
CREATE OR REPLACE FUNCTION unapi.sdist ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
CREATE OR REPLACE FUNCTION unapi.ccs ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
CREATE OR REPLACE FUNCTION unapi.ascecm ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
CREATE OR REPLACE FUNCTION unapi.bre ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
+CREATE OR REPLACE FUNCTION unapi.bmp ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
CREATE OR REPLACE FUNCTION unapi.holdings_xml ( bid BIGINT, ouid INT, org TEXT, depth INT DEFAULT NULL, includes TEXT[] DEFAULT NULL::TEXT[], slimit INT DEFAULT NULL, soffset INT DEFAULT NULL) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
CREATE OR REPLACE FUNCTION unapi.biblio_record_entry_feed ( id_list BIGINT[], format TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL, title TEXT DEFAULT NULL, description TEXT DEFAULT NULL, creator TEXT DEFAULT NULL, update_ts TEXT DEFAULT NULL, unapi_url TEXT DEFAULT NULL, header_xml XML DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
ORDER BY 1
)x)
),
+ CASE
+ WHEN ('bmp' = ANY ($5)) THEN
+ XMLELEMENT( name monograph_parts,
+ XMLAGG((SELECT unapi.bmp( id, 'xml', 'monograph_part', array_remove_item_by_value( array_remove_item_by_value($5,'bre'), 'holdings_xml'), $3, $4, $6, $7) FROM biblio.monograph_part WHERE record = $1))
+ )
+ ELSE NULL
+ END,
CASE WHEN ('acn' = ANY ('{acn,auri}'::TEXT[] || $5)) THEN
XMLELEMENT(
name volumes,
WHERE asce.id = $1;
$F$ LANGUAGE SQL;
+CREATE OR REPLACE FUNCTION unapi.bmp ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
+ SELECT XMLELEMENT(
+ name monograph_part,
+ XMLATTRIBUTES(
+ 'http://open-ils.org/spec/holdings/v1' AS xmlns,
+ 'tag:open-ils.org:U2@bmp/' || id AS id,
+ id AS ident,
+ label,
+ label_sortkey,
+ 'tag:open-ils.org:U2@bre/' || record AS record
+ ),
+ CASE
+ WHEN ('acp' = ANY ($4)) THEN
+ XMLELEMENT( name copies,
+ (SELECT XMLAGG(acp) FROM (
+ SELECT unapi.acp( cp.id, 'xml', 'copy', array_remove_item_by_value($4,'bmp'), $5, $6, $7, $8)
+ FROM asset.copy cp
+ JOIN asset.copy_part_map cpm ON (cpm.target_copy = cp.id)
+ WHERE cpm.part = $1
+ ORDER BY COALESCE(cp.copy_number,0), cp.barcode
+ LIMIT $7
+ OFFSET $8
+ )x)
+ )
+ ELSE NULL
+ END,
+ CASE WHEN ('bre' = ANY ($4)) THEN unapi.bre( record, 'marcxml', 'record', array_remove_item_by_value($4,'bmp'), $5, $6, $7, $8) ELSE NULL END
+ )
+ FROM biblio.monograph_part
+ WHERE id = $1
+ GROUP BY id, label, label_sortkey, record;
+$F$ LANGUAGE SQL;
+
CREATE OR REPLACE FUNCTION unapi.acp ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
SELECT XMLELEMENT(
name copy,
XMLELEMENT( name statcats,
CASE
WHEN ('ascecm' = ANY ($4)) THEN
- XMLAGG((SELECT unapi.acpn( stat_cat_entry, 'xml', 'statcat', array_remove_item_by_value($4,'acp'), $5, $6, $7, $8) FROM asset.stat_cat_entry_copy_map WHERE owning_copy = cp.id))
+ XMLAGG((SELECT unapi.ascecm( stat_cat_entry, 'xml', 'statcat', array_remove_item_by_value($4,'acp'), $5, $6, $7, $8) FROM asset.stat_cat_entry_copy_map WHERE owning_copy = cp.id))
ELSE NULL
END
- )
+ ),
+ CASE
+ WHEN ('bmp' = ANY ($4)) THEN
+ XMLELEMENT( name monograph_parts,
+ XMLAGG((SELECT unapi.bmp( part, 'xml', 'monograph_part', array_remove_item_by_value($4,'acp'), $5, $6, $7, $8) FROM asset.copy_part_map WHERE target_copy = cp.id))
+ )
+ ELSE NULL
+ END
)
FROM asset.copy cp
WHERE id = $1
name uris,
(SELECT XMLAGG(auri) FROM (SELECT unapi.auri(uri,'xml','uri', array_remove_item_by_value($4,'acn'), $5, $6, $7, $8) FROM asset.uri_call_number_map WHERE call_number = acn.id)x)
),
+ CASE WHEN ('acnp' = ANY ($4)) THEN unapi.acnp( acn.prefix, 'marcxml', 'prefix', array_remove_item_by_value($4,'acn'), $5, $6, $7, $8) ELSE NULL END,
+ CASE WHEN ('acns' = ANY ($4)) THEN unapi.acns( acn.suffix, 'marcxml', 'suffix', array_remove_item_by_value($4,'acn'), $5, $6, $7, $8) ELSE NULL END,
CASE WHEN ('bre' = ANY ($4)) THEN unapi.bre( acn.record, 'marcxml', 'record', array_remove_item_by_value($4,'acn'), $5, $6, $7, $8) ELSE NULL END
) AS x
FROM asset.call_number acn
JOIN actor.org_unit o ON (o.id = acn.owning_lib)
WHERE acn.id = $1
- GROUP BY acn.id, o.shortname, o.opac_visible, deleted, label, label_sortkey, label_class, owning_lib, record;
+ GROUP BY acn.id, o.shortname, o.opac_visible, deleted, label, label_sortkey, label_class, owning_lib, record, acn.prefix, acn.suffix;
+$F$ LANGUAGE SQL;
+
+CREATE OR REPLACE FUNCTION unapi.acnp ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
+ SELECT XMLELEMENT(
+ name call_number_prefix,
+ XMLATTRIBUTES(
+ 'http://open-ils.org/spec/holdings/v1' AS xmlns,
+ id AS ident,
+ label,
+ label_sortkey
+ ),
+ unapi.aou( owning_lib, $2, 'owning_lib', array_remove_item_by_value($4,'acnp'), $5, $6, $7, $8)
+ )
+ FROM asset.call_number_prefix
+ WHERE id = $1;
+$F$ LANGUAGE SQL;
+
+CREATE OR REPLACE FUNCTION unapi.acns ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
+ SELECT XMLELEMENT(
+ name call_number_suffix,
+ XMLATTRIBUTES(
+ 'http://open-ils.org/spec/holdings/v1' AS xmlns,
+ id AS ident,
+ label,
+ label_sortkey
+ ),
+ unapi.aou( owning_lib, $2, 'owning_lib', array_remove_item_by_value($4,'acns'), $5, $6, $7, $8)
+ )
+ FROM asset.call_number_suffix
+ WHERE id = $1;
$F$ LANGUAGE SQL;
CREATE OR REPLACE FUNCTION unapi.auri ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
--- /dev/null
+BEGIN;
+
+INSERT INTO config.upgrade_log (version) VALUES ('0504'); -- miker
+
+CREATE TABLE biblio.monograph_part (
+ id SERIAL PRIMARY KEY,
+ record BIGINT NOT NULL REFERENCES biblio.record_entry (id),
+ label TEXT NOT NULL,
+ label_sortkey TEXT NOT NULL,
+ CONSTRAINT record_label_unique UNIQUE (record,label)
+);
+
+CREATE OR REPLACE FUNCTION biblio.normalize_biblio_monograph_part_sortkey () RETURNS TRIGGER AS $$
+BEGIN
+ NEW.label_sortkey := REGEXP_REPLACE(
+ lpad_number_substrings(
+ naco_normalize(NEW.label),
+ '0',
+ 10
+ ),
+ E'\\s+',
+ '',
+ 'g'
+ );
+ RETURN NEW;
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE TRIGGER norm_sort_label BEFORE INSERT OR UPDATE ON biblio.monograph_part FOR EACH ROW EXECUTE PROCEDURE biblio.normalize_biblio_monograph_part_sortkey();
+
+CREATE TABLE asset.copy_part_map (
+ id SERIAL PRIMARY KEY,
+ target_copy BIGINT NOT NULL, -- points o asset.copy
+ part INT NOT NULL REFERENCES biblio.monograph_part (id) ON DELETE CASCADE
+);
+CREATE UNIQUE INDEX copy_part_map_cp_part_idx ON asset.copy_part_map (target_copy, part);
+
+CREATE OR REPLACE FUNCTION asset.normalize_affix_sortkey () RETURNS TRIGGER AS $$
+BEGIN
+ NEW.label_sortkey := REGEXP_REPLACE(
+ lpad_number_substrings(
+ naco_normalize(NEW.label),
+ '0',
+ 10
+ ),
+ E'\\s+',
+ '',
+ 'g'
+ );
+ RETURN NEW;
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE TABLE asset.call_number_prefix (
+ id SERIAL PRIMARY KEY,
+ owning_lib INT NOT NULL REFERENCES actor.org_unit (id),
+ label TEXT NOT NULL, -- i18n
+ label_sortkey TEXT
+);
+CREATE TRIGGER prefix_normalize_tgr BEFORE INSERT OR UPDATE ON asset.call_number_prefix FOR EACH ROW EXECUTE PROCEDURE asset.normalize_affix_sortkey();
+CREATE UNIQUE INDEX asset_call_number_prefix_once_per_lib ON asset.call_number_prefix (label, owning_lib);
+CREATE INDEX asset_call_number_prefix_sortkey_idx ON asset.call_number_prefix (label_sortkey);
+
+CREATE TABLE asset.call_number_suffix (
+ id SERIAL PRIMARY KEY,
+ owning_lib INT NOT NULL REFERENCES actor.org_unit (id),
+ label TEXT NOT NULL, -- i18n
+ label_sortkey TEXT
+);
+CREATE TRIGGER suffix_normalize_tgr BEFORE INSERT OR UPDATE ON asset.call_number_suffix FOR EACH ROW EXECUTE PROCEDURE asset.normalize_affix_sortkey();
+CREATE UNIQUE INDEX asset_call_number_suffix_once_per_lib ON asset.call_number_suffix (label, owning_lib);
+CREATE INDEX asset_call_number_suffix_sortkey_idx ON asset.call_number_suffix (label_sortkey);
+
+INSERT INTO asset.call_number_suffix (id, owning_lib, label) VALUES (-1, 1, '');
+INSERT INTO asset.call_number_prefix (id, owning_lib, label) VALUES (-1, 1, '');
+
+DROP INDEX IF EXISTS asset.asset_call_number_label_once_per_lib;
+
+ALTER TABLE asset.call_number
+ ADD COLUMN prefix INT NOT NULL DEFAULT -1 REFERENCES asset.call_number_prefix(id) DEFERRABLE INITIALLY DEFERRED,
+ ADD COLUMN suffix INT NOT NULL DEFAULT -1 REFERENCES asset.call_number_suffix(id) DEFERRABLE INITIALLY DEFERRED;
+
+CREATE UNIQUE INDEX asset_call_number_label_once_per_lib ON asset.call_number (record, owning_lib, label, prefix, suffix) WHERE deleted = FALSE OR deleted IS FALSE;
+
+INSERT INTO config.org_unit_setting_type ( name, label, description, datatype ) VALUES (
+ 'ui.cat.volume_copy_editor.horizontal',
+ oils_i18n_gettext(
+ 'ui.cat.volume_copy_editor.horizontal',
+ 'GUI: Horizontal layout for Volume/Copy Creator/Editor.',
+ 'coust', 'label'),
+ oils_i18n_gettext(
+ 'ui.cat.volume_copy_editor.horizontal',
+ 'The main entry point for this interface is in Holdings Maintenance, Actions for Selected Rows, Edit Item Attributes / Call Numbers / Replace Barcodes. This setting changes the top and bottom panes for that interface into left and right panes.',
+ 'coust', 'description'),
+ 'bool'
+);
+
+
+CREATE OR REPLACE FUNCTION unapi.bmp ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
+ SELECT XMLELEMENT(
+ name monograph_part,
+ XMLATTRIBUTES(
+ 'http://open-ils.org/spec/holdings/v1' AS xmlns,
+ 'tag:open-ils.org:U2@bmp/' || id AS id,
+ id AS ident,
+ label,
+ label_sortkey,
+ 'tag:open-ils.org:U2@bre/' || record AS record
+ ),
+ CASE
+ WHEN ('acp' = ANY ($4)) THEN
+ XMLELEMENT( name copies,
+ (SELECT XMLAGG(acp) FROM (
+ SELECT unapi.acp( cp.id, 'xml', 'copy', array_remove_item_by_value($4,'bmp'), $5, $6, $7, $8)
+ FROM asset.copy cp
+ JOIN asset.copy_part_map cpm ON (cpm.target_copy = cp.id)
+ WHERE cpm.part = $1
+ ORDER BY COALESCE(cp.copy_number,0), cp.barcode
+ LIMIT $7
+ OFFSET $8
+ )x)
+ )
+ ELSE NULL
+ END,
+ CASE WHEN ('bre' = ANY ($4)) THEN unapi.bre( record, 'marcxml', 'record', array_remove_item_by_value($4,'bmp'), $5, $6, $7, $8) ELSE NULL END
+ )
+ FROM biblio.monograph_part
+ WHERE id = $1
+ GROUP BY id, label, label_sortkey, record;
+$F$ LANGUAGE SQL;
+
+CREATE OR REPLACE FUNCTION unapi.acnp ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
+ SELECT XMLELEMENT(
+ name call_number_prefix,
+ XMLATTRIBUTES(
+ 'http://open-ils.org/spec/holdings/v1' AS xmlns,
+ id AS ident,
+ label,
+ label_sortkey
+ ),
+ unapi.aou( owning_lib, $2, 'owning_lib', array_remove_item_by_value($4,'acnp'), $5, $6, $7, $8)
+ )
+ FROM asset.call_number_prefix
+ WHERE id = $1;
+$F$ LANGUAGE SQL;
+
+CREATE OR REPLACE FUNCTION unapi.acns ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
+ SELECT XMLELEMENT(
+ name call_number_suffix,
+ XMLATTRIBUTES(
+ 'http://open-ils.org/spec/holdings/v1' AS xmlns,
+ id AS ident,
+ label,
+ label_sortkey
+ ),
+ unapi.aou( owning_lib, $2, 'owning_lib', array_remove_item_by_value($4,'acns'), $5, $6, $7, $8)
+ )
+ FROM asset.call_number_suffix
+ WHERE id = $1;
+$F$ LANGUAGE SQL;
+
+CREATE OR REPLACE FUNCTION unapi.holdings_xml (bid BIGINT, ouid INT, org TEXT, depth INT DEFAULT NULL, includes TEXT[] DEFAULT NULL::TEXT[], slimit INT DEFAULT NULL, soffset INT DEFAULT NULL) RETURNS XML AS $F$
+ SELECT XMLELEMENT(
+ name holdings,
+ XMLATTRIBUTES(
+ 'http://open-ils.org/spec/holdings/v1' AS xmlns,
+ CASE WHEN ('bre' = ANY ('{acn,auri}'::TEXT[] || $5)) THEN 'tag:open-ils.org:U2@bre/' || $1 || '/' || $3 ELSE NULL END AS id
+ ),
+ XMLELEMENT(
+ name counts,
+ (SELECT XMLAGG(XMLELEMENT::XML) FROM (
+ SELECT XMLELEMENT(
+ name count,
+ XMLATTRIBUTES('public' as type, depth, org_unit, coalesce(transcendant,0) as transcendant, available, visible as count, unshadow)
+ )::text
+ FROM asset.opac_ou_record_copy_count($2, $1)
+ UNION
+ SELECT XMLELEMENT(
+ name count,
+ XMLATTRIBUTES('staff' as type, depth, org_unit, coalesce(transcendant,0) as transcendant, available, visible as count, unshadow)
+ )::text
+ FROM asset.staff_ou_record_copy_count($2, $1)
+ ORDER BY 1
+ )x)
+ ),
+ CASE
+ WHEN ('bmp' = ANY ($5)) THEN
+ XMLELEMENT( name monograph_parts,
+ XMLAGG((SELECT unapi.bmp( id, 'xml', 'monograph_part', array_remove_item_by_value( array_remove_item_by_value($5,'bre'), 'holdings_xml'), $3, $4, $6, $7) FROM biblio.monograph_part WHERE record = $1))
+ )
+ ELSE NULL
+ END,
+ CASE WHEN ('acn' = ANY ('{acn,auri}'::TEXT[] || $5)) THEN
+ XMLELEMENT(
+ name volumes,
+ (SELECT XMLAGG(acn) FROM (
+ SELECT unapi.acn(acn.id,'xml','volume',array_remove_item_by_value(array_remove_item_by_value('{acn,auri}'::TEXT[] || $5,'holdings_xml'),'bre'), $3, $4, $6, $7)
+ FROM asset.call_number acn
+ WHERE acn.record = $1
+ AND EXISTS (
+ SELECT 1
+ FROM asset.copy acp
+ JOIN actor.org_unit_descendants(
+ $2,
+ (COALESCE(
+ $4,
+ (SELECT aout.depth
+ FROM actor.org_unit_type aout
+ JOIN actor.org_unit aou ON (aou.ou_type = aout.id AND aou.id = $2)
+ )
+ ))
+ ) aoud ON (acp.circ_lib = aoud.id)
+ LIMIT 1
+ )
+ ORDER BY label_sortkey
+ LIMIT $6
+ OFFSET $7
+ )x)
+ )
+ ELSE NULL END,
+ CASE WHEN ('ssub' = ANY ('{acn,auri}'::TEXT[] || $5)) THEN
+ XMLELEMENT(
+ name subscriptions,
+ (SELECT XMLAGG(ssub) FROM (
+ SELECT unapi.ssub(id,'xml','subscription','{}'::TEXT[], $3, $4, $6, $7)
+ FROM serial.subscription
+ WHERE record_entry = $1
+ )x)
+ )
+ ELSE NULL END
+ );
+$F$ LANGUAGE SQL;
+
+CREATE OR REPLACE FUNCTION unapi.acp ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
+ SELECT XMLELEMENT(
+ name copy,
+ XMLATTRIBUTES(
+ 'http://open-ils.org/spec/holdings/v1' AS xmlns,
+ 'tag:open-ils.org:U2@acp/' || id AS id,
+ create_date, edit_date, copy_number, circulate, deposit,
+ ref, holdable, deleted, deposit_amount, price, barcode,
+ circ_modifier, circ_as_type, opac_visible
+ ),
+ unapi.ccs( status, $2, 'status', array_remove_item_by_value($4,'acp'), $5, $6, $7, $8),
+ unapi.acl( location, $2, 'location', array_remove_item_by_value($4,'acp'), $5, $6, $7, $8),
+ unapi.aou( circ_lib, $2, 'circ_lib', array_remove_item_by_value($4,'acp'), $5, $6, $7, $8),
+ unapi.aou( circ_lib, $2, 'circlib', array_remove_item_by_value($4,'acp'), $5, $6, $7, $8),
+ CASE WHEN ('acn' = ANY ($4)) THEN unapi.acn( call_number, $2, 'call_number', array_remove_item_by_value($4,'acp'), $5, $6, $7, $8) ELSE NULL END,
+ XMLELEMENT( name copy_notes,
+ CASE
+ WHEN ('acpn' = ANY ($4)) THEN
+ XMLAGG((SELECT unapi.acpn( id, 'xml', 'copy_note', array_remove_item_by_value($4,'acp'), $5, $6, $7, $8) FROM asset.copy_note WHERE owning_copy = cp.id AND pub))
+ ELSE NULL
+ END
+ ),
+ XMLELEMENT( name statcats,
+ CASE
+ WHEN ('ascecm' = ANY ($4)) THEN
+ XMLAGG((SELECT unapi.ascecm( stat_cat_entry, 'xml', 'statcat', array_remove_item_by_value($4,'acp'), $5, $6, $7, $8) FROM asset.stat_cat_entry_copy_map WHERE owning_copy = cp.id))
+ ELSE NULL
+ END
+ ),
+ CASE
+ WHEN ('bmp' = ANY ($4)) THEN
+ XMLELEMENT( name monograph_parts,
+ XMLAGG((SELECT unapi.bmp( part, 'xml', 'monograph_part', array_remove_item_by_value($4,'acp'), $5, $6, $7, $8) FROM asset.copy_part_map WHERE target_copy = cp.id))
+ )
+ ELSE NULL
+ END
+ )
+ FROM asset.copy cp
+ WHERE id = $1
+ GROUP BY id, status, location, circ_lib, call_number, create_date, edit_date, copy_number, circulate, deposit, ref, holdable, deleted, deposit_amount, price, barcode, circ_modifier, circ_as_type, opac_visible;
+$F$ LANGUAGE SQL;
+
+CREATE OR REPLACE FUNCTION unapi.acn ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
+ SELECT XMLELEMENT(
+ name volume,
+ XMLATTRIBUTES(
+ 'http://open-ils.org/spec/holdings/v1' AS xmlns,
+ 'tag:open-ils.org:U2@acn/' || acn.id AS id,
+ o.shortname AS lib,
+ o.opac_visible AS opac_visible,
+ deleted, label, label_sortkey, label_class, record
+ ),
+ unapi.aou( owning_lib, $2, 'owning_lib', array_remove_item_by_value($4,'acn'), $5, $6, $7, $8),
+ XMLELEMENT( name copies,
+ CASE
+ WHEN ('acp' = ANY ($4)) THEN
+ (SELECT XMLAGG(acp) FROM (
+ SELECT unapi.acp( cp.id, 'xml', 'copy', array_remove_item_by_value($4,'acn'), $5, $6, $7, $8)
+ FROM asset.copy cp
+ JOIN actor.org_unit_descendants(
+ (SELECT id FROM actor.org_unit WHERE shortname = $5),
+ (COALESCE($6,(SELECT aout.depth FROM actor.org_unit_type aout JOIN actor.org_unit aou ON (aou.ou_type = aout.id AND aou.shortname = $5))))
+ ) aoud ON (cp.circ_lib = aoud.id)
+ WHERE cp.call_number = acn.id
+ ORDER BY COALESCE(cp.copy_number,0), cp.barcode
+ LIMIT $7
+ OFFSET $8
+ )x)
+ ELSE NULL
+ END
+ ),
+ XMLELEMENT(
+ name uris,
+ (SELECT XMLAGG(auri) FROM (SELECT unapi.auri(uri,'xml','uri', array_remove_item_by_value($4,'acn'), $5, $6, $7, $8) FROM asset.uri_call_number_map WHERE call_number = acn.id)x)
+ ),
+ CASE WHEN ('acnp' = ANY ($4)) THEN unapi.acnp( acn.prefix, 'marcxml', 'prefix', array_remove_item_by_value($4,'acn'), $5, $6, $7, $8) ELSE NULL END,
+ CASE WHEN ('acns' = ANY ($4)) THEN unapi.acns( acn.suffix, 'marcxml', 'suffix', array_remove_item_by_value($4,'acn'), $5, $6, $7, $8) ELSE NULL END,
+ CASE WHEN ('bre' = ANY ($4)) THEN unapi.bre( acn.record, 'marcxml', 'record', array_remove_item_by_value($4,'acn'), $5, $6, $7, $8) ELSE NULL END
+ ) AS x
+ FROM asset.call_number acn
+ JOIN actor.org_unit o ON (o.id = acn.owning_lib)
+ WHERE acn.id = $1
+ GROUP BY acn.id, o.shortname, o.opac_visible, deleted, label, label_sortkey, label_class, owning_lib, record, acn.prefix, acn.suffix;
+$F$ LANGUAGE SQL;
+
+
+COMMIT;
+
copyList.push(copy);
}
if (xulG) {
- // If we need to, we can pass in an update_copy function to handle the update instead of volume_item_creator
xulG.volume_item_creator( { 'existing_copies' : copyList } );
}
} catch(E) {
--- /dev/null
+dojo.require('dojox.grid.DataGrid');
+dojo.require('openils.widget.AutoGrid');
+dojo.require('dojox.grid.cells.dijit');
+dojo.require('dojo.data.ItemFileWriteStore');
+dojo.require('dijit.form.CurrencyTextBox');
+dojo.require('dijit.Dialog');
+dojo.require('dojox.widget.PlaceholderMenuItem');
+dojo.require('fieldmapper.OrgUtils');
+dojo.require('dijit.form.FilteringSelect');
+dojo.require('openils.PermaCrud');
+dojo.require('openils.widget.OrgUnitFilteringSelect');
+
+var thingContextOrg;
+var thingList;
+
+/** really need to put this in a shared location... */
+function getOrgInfo(rowIndex, item) {
+ if(!item) return '';
+ var orgId = this.grid.store.getValue(item, this.field);
+ return fieldmapper.aou.findOrgUnit(orgId).shortname();
+}
+
+function thingInit() {
+
+ thingGrid.disableSelectorForRow = function(rowIdx) {
+ var item = thingGrid.getItem(rowIdx);
+ return (thingGrid.store.getValue(item, 'id') < 0);
+ }
+
+ buildGrid();
+ var connect = function() {
+ dojo.connect(thingContextOrgSelect, 'onChange',
+ function() {
+ thingContextOrg = this.getValue();
+ thingGrid.resetStore();
+ buildGrid();
+ }
+ );
+ };
+ // go ahead and let staff see everything
+ new openils.User().buildPermOrgSelector('STAFF_LOGIN', thingContextOrgSelect, null, connect);
+}
+
+function buildGrid() {
+ if(thingContextOrg == null)
+ thingContextOrg = openils.User.user.ws_ou();
+
+ fieldmapper.standardRequest(
+ ['open-ils.pcrud', 'open-ils.pcrud.search.acnp.atomic'],
+ { async: true,
+ params: [
+ openils.User.authtoken,
+ {"owning_lib":fieldmapper.aou.descendantNodeList(thingContextOrg,true)},
+ {"order_by":{"acnp":"label_sortkey"}}
+ ],
+ oncomplete: function(r) {
+ if(thingList = openils.Util.readResponse(r)) {
+ thingList = openils.Util.objectSort(thingList);
+ dojo.forEach(thingList,
+ function(e) {
+ thingGrid.store.newItem(acnp.toStoreItem(e));
+ }
+ );
+ }
+ }
+ }
+ );
+}
+
+openils.Util.addOnLoad(thingInit);
+
+
--- /dev/null
+dojo.require('dojox.grid.DataGrid');
+dojo.require('openils.widget.AutoGrid');
+dojo.require('dojox.grid.cells.dijit');
+dojo.require('dojo.data.ItemFileWriteStore');
+dojo.require('dijit.form.CurrencyTextBox');
+dojo.require('dijit.Dialog');
+dojo.require('dojox.widget.PlaceholderMenuItem');
+dojo.require('fieldmapper.OrgUtils');
+dojo.require('dijit.form.FilteringSelect');
+dojo.require('openils.PermaCrud');
+dojo.require('openils.widget.OrgUnitFilteringSelect');
+
+var thingContextOrg;
+var thingList;
+
+/** really need to put this in a shared location... */
+function getOrgInfo(rowIndex, item) {
+ if(!item) return '';
+ var orgId = this.grid.store.getValue(item, this.field);
+ return fieldmapper.aou.findOrgUnit(orgId).shortname();
+}
+
+function thingInit() {
+
+ thingGrid.disableSelectorForRow = function(rowIdx) {
+ var item = thingGrid.getItem(rowIdx);
+ return (thingGrid.store.getValue(item, 'id') < 0);
+ }
+
+ buildGrid();
+ var connect = function() {
+ dojo.connect(thingContextOrgSelect, 'onChange',
+ function() {
+ thingContextOrg = this.getValue();
+ thingGrid.resetStore();
+ buildGrid();
+ }
+ );
+ };
+ // go ahead and let staff see everything
+ new openils.User().buildPermOrgSelector('STAFF_LOGIN', thingContextOrgSelect, null, connect);
+}
+
+function buildGrid() {
+ if(thingContextOrg == null)
+ thingContextOrg = openils.User.user.ws_ou();
+
+ fieldmapper.standardRequest(
+ ['open-ils.pcrud', 'open-ils.pcrud.search.acns.atomic'],
+ { async: true,
+ params: [
+ openils.User.authtoken,
+ {"owning_lib":fieldmapper.aou.descendantNodeList(thingContextOrg,true)},
+ {"order_by":{"acns":"label_sortkey"}}
+ ],
+ oncomplete: function(r) {
+ if(thingList = openils.Util.readResponse(r)) {
+ thingList = openils.Util.objectSort(thingList);
+ dojo.forEach(thingList,
+ function(e) {
+ thingGrid.store.newItem(acns.toStoreItem(e));
+ }
+ );
+ }
+ }
+ }
+ );
+}
+
+openils.Util.addOnLoad(thingInit);
+
+
<!ENTITY staff.cat.opac.copy_browse.accesskey "H">
<!ENTITY staff.cat.opac.copy_browse.label "Holdings Maintenance">
<!ENTITY staff.cat.opac.default.label "Set bottom interface as Default">
+<!ENTITY staff.cat.opac.manage_parts.accesskey "P">
+<!ENTITY staff.cat.opac.manage_parts.label "Manage Parts">
<!ENTITY staff.cat.opac.marc_edit.accesskey "E">
<!ENTITY staff.cat.opac.marc_edit.label "MARC Edit">
<!ENTITY staff.cat.opac.marc_view.accesskey "V">
<!ENTITY staff.main.menu.admin.server_admin.conify.copy_status.label "Copy Statuses">
<!ENTITY staff.main.menu.admin.server_admin.conify.marc_record_attrs.label "MARC Record Attributes">
<!ENTITY staff.main.menu.admin.server_admin.conify.coded_value_maps.label "MARC Coded Value Maps">
+<!ENTITY staff.main.menu.admin.server_admin.conify.acn_prefix.label "Call Number Prefixes">
+<!ENTITY staff.main.menu.admin.server_admin.conify.acn_suffix.label "Call Number Suffixes">
<!ENTITY staff.main.menu.admin.server_admin.conify.billing_type.label "Billing Types">
<!ENTITY staff.main.menu.admin.server_admin.conify.z3950_source.label "Z39.50 Servers">
<!ENTITY staff.main.menu.admin.server_admin.conify.circulation_modifier.label "Circulation Modifiers">
<!ENTITY staff.cat.bib_brief.title.label "Title:">
<!ENTITY staff.cat.bib_brief.title.accesskey "">
<!ENTITY staff.cat.bib_brief.view_marc "View MARC">
+<!ENTITY staff.cat.bib_brief.add_volumes "Add Volumes">
<!ENTITY staff.cat.bib_brief.author.label "Author:">
<!ENTITY staff.cat.bib_brief.author.accesskey "">
<!ENTITY staff.cat.bib_brief.edition.label "Edition:">
<!ENTITY staff.cat.copy_browser.actions.cmd_create_brt.accesskey "K">
<!ENTITY staff.cat.copy_browser.actions.sel_patron.label "Show Last Few Circulations">
<!ENTITY staff.cat.copy_browser.actions.sel_patron.accesskey "L">
-<!ENTITY staff.cat.copy_browser.actions.cmd_edit_items.label "Edit Item Attributes">
+<!ENTITY staff.cat.copy_browser.actions.cmd_edit_items.label "Edit Item Attributes / Call Numbers / Replace Barcodes">
<!ENTITY staff.cat.copy_browser.actions.cmd_edit_items.accesskey "E">
<!ENTITY staff.cat.copy_browser.actions.cmd_transfer_items.label "Transfer Items to Previously Marked Volume">
<!ENTITY staff.cat.copy_browser.actions.cmd_transfer_items.accesskey "T">
<!ENTITY staff.cat.copy_browser.actions.sel_mark_items_missing.accesskey "g">
<!ENTITY staff.cat.copy_browser.actions.cmd_print_spine_labels.label "Print Item Spine Labels">
<!ENTITY staff.cat.copy_browser.actions.cmd_print_spine_labels.accesskey "P">
-<!ENTITY staff.cat.copy_browser.actions.cmd_replace_barcode.label "Replace Barcode">
<!ENTITY staff.cat.copy_browser.actions.save_columns.label "Save Columns">
<!ENTITY staff.cat.copy_browser.actions.cmd_refresh_list.label "Refresh Listing">
<!ENTITY staff.cat.copy_browser.actions.cmd_refresh_list.accesskey "R">
<!ENTITY staff.cat.copy_browser.holdings_maintenance.sel_patron.label "Show Last Few Circulations">
<!ENTITY staff.cat.copy_browser.holdings_maintenance.sel_patron.accesskey "L">
-<!ENTITY staff.cat.copy_browser.holdings_maintenance.cmd_edit_items.label "Edit Item Attributes">
+<!ENTITY staff.cat.copy_browser.holdings_maintenance.cmd_edit_items.label "Edit Item Attributes / Call Numbers / Replace Barcodes">
<!ENTITY staff.cat.copy_browser.holdings_maintenance.cmd_edit_items.accesskey "E">
<!ENTITY staff.cat.copy_browser.holdings_maintenance.cmd_transfer_items.label "Transfer Items to Previously Marked Volume">
<!ENTITY staff.cat.copy_browser.holdings_maintenance.cmd_transfer_items.accesskey "T">
<!ENTITY staff.cat.volume_copy_creator.print_labels.accesskey "P">
<!ENTITY staff.cat.volume_copy_creator.library_label.value "Library">
<!ENTITY staff.cat.volume_copy_creator.num_of_volumes_label.value "# of volumes">
+<!ENTITY staff.cat.volume_copy_creator.batch_bar "BATCH">
+<!ENTITY staff.cat.volume_copy_creator.batch_bar.call_number.classification "Classification:">
+<!ENTITY staff.cat.volume_copy_creator.batch_bar.call_number.prefix "Prefix:">
+<!ENTITY staff.cat.volume_copy_creator.batch_bar.call_number.label.label "Label:">
+<!ENTITY staff.cat.volume_copy_creator.batch_bar.call_number.label.accesskey "L">
+<!ENTITY staff.cat.volume_copy_creator.batch_bar.call_number.suffix "Suffix:">
<!ENTITY staff.cat.volume_editor.title "Volumes">
<!ENTITY staff.cat.volume_editor.caption.label "Volume Editor">
<!ENTITY staff.cat.volume_editor.modify.label "Modify">
<!ENTITY staff.cat.volume_editor.cancel.accesskey "C">
<!ENTITY staff.cat.volume_editor.automerge.label "Auto-Merge on Volume Collision">
<!ENTITY staff.cat.volume_editor.automerge.accesskey "A">
+<!ENTITY staff.cat.volume_editor.owning_lib "Owning lib">
+<!ENTITY staff.cat.volume_editor.classification "Classification">
+<!ENTITY staff.cat.volume_editor.prefix "Prefix">
+<!ENTITY staff.cat.volume_editor.label "Label">
+<!ENTITY staff.cat.volume_editor.suffix "Suffix">
<!ENTITY staff.cat.z3950.marc_import.label "MARC Import via Z39.50">
<!ENTITY staff.cat.z3950.marc_import.accesskey "I">
<!ENTITY staff.cat.z3950.service_credentials.label "Service and Credentials">
<!-- =================================================================
MyOPAC Holds Page
================================================================= -->
+
<!ENTITY myopac.holds.formats "Formats">
<!ENTITY myopac.holds.location "Pickup Location">
<!ENTITY myopac.holds.edit "Edit">
Rdetail
================================================================= -->
<!ENTITY rdetail.print "print these details">
+<!ENTITY rdetail.cn.part "Part">
<!ENTITY rdetail.cn.barcode "Barcode">
<!ENTITY rdetail.cn.location "Location">
<!ENTITY rdetail.cn.hold.age "Age Hold Protection">
<!ENTITY common.call.number.label "Call Number:">
<!ENTITY common.isbn.label "ISBN:">
<!ENTITY common.issn.label "ISSN:">
+<!ENTITY common.mono_parts.label "Monograph Parts:">
<!ENTITY common.copy.barcode.label "Copy Barcode:">
<!ENTITY common.issuance_label.label "Issuance Label:">
<!ENTITY common.hold.place "Place hold for my account">
function cpdDrawCopy(r) {
var copy = r.getResultObject();
var row = r.row;
+ var trow = r.args.templateRow;
if (r.args.copy_location && copy.location().name() != r.args.copy_location) {
hideMe(row);
$n(row, 'location').appendChild(text(copy.location().name()));
$n(row, 'status').appendChild(text(copy.status().name()));
+ // append comma-separated list of part this copy is linked to
+ if(copy.parts() && copy.parts().length) {
+ unHideMe($n(trow, 'copy_part_label'));
+ unHideMe($n(row, 'copy_part'));
+ for(var i = 0; i < copy.parts().length; i++) {
+ var part = copy.parts()[i];
+ var node = $n(row, 'copy_part');
+ if(i > 0) node.appendChild(text(','));
+ node.appendChild(text(part.label()));
+ }
+ }
+
if(isXUL()) {
/* show the hold link */
var l = $n(row, 'copy_hold_link');
T : 'record',
V : 'volume',
I : 'issuance',
- C : 'copy'
+ C : 'copy',
+ P : 'part'
};
} else if( type == 'I' ) {
_h_set_issuance(args, doneCallback);
+ } else if( type == 'P' ) {
+ _h_set_parts(args, doneCallback);
+
} else {
- if( type == 'T' ) {
+ if( type == 'T') {
_h_set_rec(args, doneCallback);
} else {
_h_set_rec_descriptors(args, doneCallback);
return args;
}
+function _h_set_parts(args, doneCallback) {
+
+ var preq = new Request(
+ 'open-ils.fielder:open-ils.fielder.bmp.atomic',
+ {"cache":1, "fields":["label", "record"],"query": {"id":args.part}}
+ );
+
+ preq.callback(
+ function(r) {
+ var part = r.getResultObject()[0];
+ args.record = part.record;
+ args.partObject = part;
+ _h_set_rec(args, doneCallback);
+ }
+ );
+
+ preq.send();
+}
+
function _h_set_vol(args, doneCallback) {
if( args.volumeObject ) {
else
args.recordObject = findRecord( args.record, 'T' );
- if( args.type == 'T' || args.type == 'M' )
+ if( args.type == 'T' || args.type == 'M' ) {
_h_set_rec_descriptors(args, doneCallback);
- else
+ //} else if(args.type == 'P') {
+ //_h_get_parts(args, doneCallback);
+ } else {
if(doneCallback) doneCallback(args);
+ }
}
args.pickup_lib = getSelectorVal($('holds_org_selector'));
if(args.pickup_lib === null)
- args.pickup_lib = holdArgs.recipient.home_ou();
+ args.pickup_lib = args.recipient.home_ou();
// grab the list of record desciptors attached to this records metarecord
if( ! args.recordDescriptors ) {
req.callback(
function(r) {
var data = r.getResultObject();
- holdArgs.recordDescriptors = args.recordDescriptors = data.descriptors;
- holdArgs.metarecord = args.metarecord = data.metarecord;
+ args.recordDescriptors = args.recordDescriptors = data.descriptors;
+ args.metarecord = args.metarecord = data.metarecord;
if( args.type == 'M' && ! args.metarecordObject)
- holdArgs.metarecordObject = args.metarecordObject = findRecord(args.metarecord, 'M');
+ args.metarecordObject = args.metarecordObject = findRecord(args.metarecord, 'M');
- if(doneCallback) doneCallback(args);
+ _h_get_parts(args, doneCallback);
}
);
req.send();
} else {
- if(doneCallback) doneCallback(args);
+ _h_get_parts(args, doneCallback);
}
return args;
}
+function _h_get_parts(args, doneCallback) {
+
+ if(args.type == 'M' || args.editHold || args.holdParts) {
+ if(doneCallback)
+ doneCallback(args);
+
+ } else {
+
+ var req = new Request(
+ 'open-ils.search:open-ils.search.biblio.record_hold_parts',
+ {pickup_lib: args.pickup_lib, record: args.record}
+ );
+
+ req.callback(
+ function(r) {
+ args.recordParts = r.getResultObject();
+ if(doneCallback)
+ doneCallback(args);
+ }
+ );
+ req.send();
+ }
+}
+
function holdsDrawWindow() {
hideMe($('holds_issuance_row'));
}
+ if(holdArgs.recordParts && holdArgs.recordParts.length) {
+ var selector = $('holds_parts_selector');
+ unHideMe($('holds_parts_row'));
+ unHideMe(selector);
+
+ var nodeList = [];
+ dojo.forEach(selector.options,
+ function(node) { if(node.value != '') nodeList.push(node) } );
+
+ dojo.forEach(nodeList, function(node) { selector.removeChild(node); });
+
+ dojo.forEach(
+ holdArgs.recordParts,
+ function(part) {
+ insertSelectorVal(selector, -1, part.label, part.id);
+ }
+ );
+
+ } else if(holdArgs.type == 'P') {
+ unHideMe($('holds_parts_row'));
+ unHideMe($('holds_parts_label'));
+ appendClear( $('holds_parts_label'), text(holdArgs.partObject.label));
+ }
+
removeChildren($('holds_format'));
var mods_formats = rec.types_of_resource();
if(type=='M') opt.selected=true;
unHideMe(opt);
}
+
+ // If the user selects a format, P-type holds are no longer an option
+ // disable and reset the P-type form control
+ selector.onchange = function() {
+ var partsSel = $('holds_parts_selector');
+ for(var i = 0; i < selector.options.length; i++) {
+ if(selector.options[i].selected) {
+ partsSel.selectedIndex = 0; // none selected
+ partsSel.disabled = true;
+ return;
+ }
+ }
+ partsSel.disabled = false;
+ }
}
function findFormatSelectorOptByParts( sel, val ) {
hold_type : holdArgs.type,
patronid : holdArgs.recipient.id(),
depth : 0,
- pickup_lib : pickuplib
+ pickup_lib : pickuplib,
+ partid : holdArgs.part
};
if(recurse) {
else
hold.email_notify(0);
+ var part = getSelectorVal($('holds_parts_selector'));
+ if(part) {
+ holdArgs.type = 'P';
+ holdArgs.part = part;
+ }
+
var target = holdArgs[holdTargetTypeMap[holdArgs.type]];
+ // a mono part is selected
+
hold.pickup_lib(org);
//hold.request_lib(org);
hold.requestor(holdArgs.requestor.id());
function myOPACDrawHoldTitle(hold) {
var method;
- if( hold.hold_type() == 'T' || hold.hold_type() == 'M' ) {
+ if( hold.hold_type() == 'T' || hold.hold_type() == 'M') {
if(hold.hold_type() == "M") method = FETCH_MRMODS;
if(hold.hold_type() == "T") method = FETCH_RMODS;
var req = new Request(method, hold.target());
function _myOPACFleshHoldTitle(hold, holdObjects) {
- var record = holdObjects.recordObject;
+ var record = holdObjects.recordObject;
var volume = holdObjects.volumeObject;
var copy = holdObjects.copyObject;
buildTitleDetailLink(record, title_link);
buildSearchLink(STYPE_AUTHOR, record.author(), author_link);
+ if(hold.hold_type() == 'P') {
+ unHideMe($n(row, 'vol_copy'));
+ $n(row, 'part').appendChild(text(holdObjects.partObject.label));
+ }
+
if( volume ) {
$n(row, 'volume').appendChild(text(volume.label()));
unHideMe($n(row, 'vol_copy'));
runEvt("result", "preCollectRecords");
var x = 0;
+ // don't perform rdetail redirect if user was on rdetail and cliecked Back
+ if(findCurrentPage() == RRESULT && isXUL()) {
+ if(ids.length == 1 && !xulG.fromBack) {
+ var args = {};
+ args.page = RDETAIL;
+ args[PARAM_OFFSET] = 0;
+ args[PARAM_RID] = ids[0];
+ location.href = buildOPACLink(args);
+ }
+ }
+
if (!base) base = 0;
if( rresultIsPaged ) base = 0;
<td class='holds_cell' id='holds_physical_desc'> </td>
</tr>
+ <tr class='hide_me' id='holds_parts_row'>
+ <td class='holds_cell'>&common.mono_parts.label;</td>
+ <td class='holds_cell'>
+ <span class='hide_me' id='holds_parts_label'></span>
+ <select id='holds_parts_selector' class='hide_me'>
+ <option value=''></option>
+ </select>
+ </td>
+ </tr>
+
<tr class='hide_me' id='holds_cn_row'>
<td class='holds_cell'>&common.call.number.label;</td>
<td class='holds_cell'><b id='holds_cn'/> </td>
<td name='myopac_holds_title'>
<a href='javascript:void(0);' name='myopac_holds_title_link'> </a>
<div name='vol_copy' style='border: 1px solid #808080; width:98%; margin-top: 2px;' class='hide_me'>
- <div style='font-size: 90%' name='volume'/>
- <div style='font-size: 90%' name='copy'/>
+ <div style='font-size: 90%' name='part'></div>
+ <div style='font-size: 90%' name='volume'></div>
+ <div style='font-size: 90%' name='copy'></div>
</div>
</td>
<td width='33%'>&rdetail.cn.barcode;</td>
<td>&common.status;</td>
<td>&rdetail.cn.location;</td>
+ <td name='copy_part_label' class='hide_me'>&rdetail.cn.part;</td>
<td name='age_protect_label' class='hide_me'>&rdetail.cn.hold.age;</td>
<td name='create_date_label' class='hide_me'>&rdetail.cn.genesis;</td>
<td name='holdable_label' class='hide_me'>&rdetail.cn.holdable;</td>
<td name='status'> </td>
<td name='location'> </td>
+ <td name='copy_part' class='hide_me'> </td>
<td name='age_protect_value' class='hide_me'>&rdetail.cn.disabled;</td>
<td name='create_date_value' class='hide_me'> </td>
--- /dev/null
+[% WRAPPER default/base.tt2 %]
+[% ctx.page_title = 'Configure Monograph Parts' %]
+<div dojoType="dijit.layout.ContentPane" layoutAlign="client">
+ <div dojoType="dijit.layout.ContentPane" layoutAlign="top" class='oils-header-panel'>
+ <div>Monograph Parts</div>
+ <div>
+ <button dojoType='dijit.form.Button' onClick='monoPartGrid.showCreateDialog()'>New Monograph Part</button>
+ <button dojoType='dijit.form.Button' onClick='monoPartGrid.deleteSelected()'>Delete Selected</button>
+ </div>
+ </div>
+ <div>
+ <table jsId="monoPartGrid"
+ dojoType="openils.widget.AutoGrid"
+ autoHeight='true'
+ fieldOrder="['label']"
+ suppressFields="['id','record','label_sortkey']"
+ suppressEditFields="['id','label_sortkey']"
+ query="{id: null}"
+ fmClass='bmp'
+ editOnEnter='true'/>
+</div>
+
+<script type="text/javascript">
+ dojo.require('openils.CGI');
+ dojo.require('openils.Util');
+ dojo.require('openils.widget.AutoGrid');
+
+ var cgi = new openils.CGI();
+ openils.Util.addOnLoad( function() {
+ monoPartGrid.overrideEditWidgets.record = new dijit.form.TextBox({"disabled": true});
+ monoPartGrid.overrideEditWidgets.record.shove = { create : cgi.param('r') };
+ monoPartGrid.loadAll({order_by : {bmp : 'label'}}, {record : cgi.param('r')});
+ });
+</script>
+[% END %]
+
+
--- /dev/null
+[% WRAPPER default/base.tt2 %]
+[% ctx.page_title = 'Call Number Prefixes' %]
+<script type="text/javascript" src='[% ctx.media_prefix %]/js/ui/default/conify/global/config/acn_prefix.js'> </script>
+
+<!-- grid -->
+
+ <div dojoType="dijit.layout.ContentPane" layoutAlign="client">
+ <div dojoType="dijit.layout.ContentPane" layoutAlign="top" class='oils-header-panel'>
+ <div>Call Number Prefixes</div>
+ <div>
+ <button dojoType='dijit.form.Button' onClick='thingGrid.showCreateDialog()'>New Prefix</button>
+ <button dojoType='dijit.form.Button' onClick='thingGrid.deleteSelected()'>Delete Selected</button>
+ </div>
+ </div>
+ <div>
+ <span>Context Org Unit</span>
+ <select dojoType="openils.widget.OrgUnitFilteringSelect" jsId='thingContextOrgSelect'
+ searchAttr='shortname' labelAttr='shortname'> </select>
+ </div>
+ <table jsId="thingGrid"
+ dojoType="openils.widget.AutoGrid"
+ fieldOrder="['id', 'label', 'owning_lib']"
+ suppressFields="['label_sortkey']"
+ suppressEditFields="['label_sortkey']"
+ query="{id: '*'}"
+ defaultCellWidth='20'
+ fmClass='acnp'
+ editOnEnter='true'>
+ <thead>
+ <tr><th field='owning_lib' get='getOrgInfo'/></tr>
+ </thead>
+ </table>
+ </div>
+</div>
+[% END %]
+
+
--- /dev/null
+[% WRAPPER default/base.tt2 %]
+[% ctx.page_title = 'Call Number Suffixes' %]
+<script type="text/javascript" src='[% ctx.media_prefix %]/js/ui/default/conify/global/config/acn_suffix.js'> </script>
+
+<!-- grid -->
+
+ <div dojoType="dijit.layout.ContentPane" layoutAlign="client">
+ <div dojoType="dijit.layout.ContentPane" layoutAlign="top" class='oils-header-panel'>
+ <div>Call Number Suffixes</div>
+ <div>
+ <button dojoType='dijit.form.Button' onClick='thingGrid.showCreateDialog()'>New Suffix</button>
+ <button dojoType='dijit.form.Button' onClick='thingGrid.deleteSelected()'>Delete Selected</button>
+ </div>
+ </div>
+ <div>
+ <span>Context Org Unit</span>
+ <select dojoType="openils.widget.OrgUnitFilteringSelect" jsId='thingContextOrgSelect'
+ searchAttr='shortname' labelAttr='shortname'> </select>
+ </div>
+ <table jsId="thingGrid"
+ dojoType="openils.widget.AutoGrid"
+ fieldOrder="['id', 'label', 'owning_lib']"
+ suppressFields="['label_sortkey']"
+ suppressEditFields="['label_sortkey']"
+ query="{id: '*'}"
+ defaultCellWidth='20'
+ fmClass='acns'
+ editOnEnter='true'>
+ <thead>
+ <tr><th field='owning_lib' get='getOrgInfo'/></tr>
+ </thead>
+ </table>
+ </div>
+</div>
+[% END %]
+
+
}
}
+ // If we don't clear these, then things like obj.list['acnp_for_lib_1'] may stick around
+ obj.hash = {}; obj.list = {};
+
this.chain = [];
this.chain.push(
this.chain.push(
function() {
var f = gen_fm_retrieval_func(
+ 'acnc',
+ [
+ api.FM_ACNC_RETRIEVE_VIA_PCRUD.app,
+ api.FM_ACNC_RETRIEVE_VIA_PCRUD.method,
+ [ obj.session.key, {"id":{"!=":null}}, {"order_by":{"acnc":"name"}} ],
+ false
+ ]
+ );
+ try {
+ f();
+ } catch(E) {
+ var error = 'Error: ' + js2JSON(E);
+ obj.error.sdump('D_ERROR',error);
+ throw(E);
+ }
+ }
+ );
+
+ this.chain.push(
+ function() {
+ var f = gen_fm_retrieval_func(
'ahrcc',
[
api.FM_AHRCC_PCRUD_SEARCH.app,
}
);
-
this.chain.push(
function() {
var f = gen_fm_retrieval_func(
this.chain.push(
function() {
var f = gen_fm_retrieval_func(
+ 'acnp',
+ [
+ api.FM_ACNP_RETRIEVE_VIA_PCRUD.app,
+ api.FM_ACNP_RETRIEVE_VIA_PCRUD.method,
+ [ obj.session.key, {"owning_lib":{"=":obj.list.au[0].ws_ou()}}, {"order_by":{"acnp":"label_sortkey"}} ],
+ false
+ ]
+ );
+ try {
+ f();
+ obj.list['acnp_for_lib_'+obj.list.au[0].ws_ou()] = obj.list.acnp;
+ } catch(E) {
+ var error = 'Error: ' + js2JSON(E);
+ obj.error.sdump('D_ERROR',error);
+ throw(E);
+ }
+ }
+ );
+
+ this.chain.push(
+ function() {
+ var f = gen_fm_retrieval_func(
+ 'acns',
+ [
+ api.FM_ACNS_RETRIEVE_VIA_PCRUD.app,
+ api.FM_ACNS_RETRIEVE_VIA_PCRUD.method,
+ [ obj.session.key, {"owning_lib":{"=":obj.list.au[0].ws_ou()}}, {"order_by":{"acns":"label_sortkey"}} ],
+ false
+ ]
+ );
+ try {
+ f();
+ obj.list['acns_for_lib_'+obj.list.au[0].ws_ou()] = obj.list.acns;
+ } catch(E) {
+ var error = 'Error: ' + js2JSON(E);
+ obj.error.sdump('D_ERROR',error);
+ throw(E);
+ }
+ }
+ );
+
+ this.chain.push(
+ function() {
+ var f = gen_fm_retrieval_func(
'cbt',
[
api.FM_CBT_RETRIEVE.app,
function update_modal_xulG(v) {
try {
+ if (typeof xulG != "undefined" && xulG.not_modal) {
+ xulG = v;
+ xulG.not_modal = true;
+ return;
+ }
+
JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
var key = location.pathname + location.search + location.hash;
if (typeof data.modal_xulG_stack != 'undefined' && typeof data.modal_xulG_stack[key] != 'undefined') {
}
if (typeof _params.no_xulG == 'undefined') {
if (typeof _params.modal_xulG != 'undefined') {
- JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
- var key = location.pathname + location.search + location.hash;
- //dump('xul_param, considering modal key = ' + key + '\n');
- if (typeof data.modal_xulG_stack != 'undefined' && typeof data.modal_xulG_stack[key] != 'undefined') {
- xulG = data.modal_xulG_stack[key][ data.modal_xulG_stack[key].length - 1 ];
+ if (typeof xulG != 'undefined' && xulG.not_modal) {
+ // for interfaces that used to be modal but aren't now, do nothing
+ } else {
+ JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
+ var key = location.pathname + location.search + location.hash;
+ //dump('xul_param, considering modal key = ' + key + '\n');
+ if (typeof data.modal_xulG_stack != 'undefined' && typeof data.modal_xulG_stack[key] != 'undefined') {
+ xulG = data.modal_xulG_stack[key][ data.modal_xulG_stack[key].length - 1 ];
+ }
}
}
if (typeof xulG == 'object' && typeof xulG[ param_name ] != 'undefined') {
function set_brief_view() {
var url = xulG.url_prefix( urls.XUL_BIB_BRIEF ) + '?docid=' + window.escape(docid);
dump('spawning ' + url + '\n');
+
+ var content_params = {
+ 'set_tab_name' : function(n) {
+ if (typeof window.xulG == 'object' && typeof window.xulG.set_tab_name == 'function') {
+ try { window.xulG.set_tab_name(document.getElementById('offlineStrings').getFormattedString("cat.bib_record", [n])); } catch(E) { alert(E); }
+ } else {
+ dump('no set_tab_name\n');
+ }
+ }
+ };
+
+ ["url_prefix", "new_tab", "set_tab", "close_tab", "new_patron_tab",
+ "set_patron_tab", "volume_item_creator", "get_new_session",
+ "holdings_maintenance_tab", "open_chrome_window", "url_prefix",
+ "network_meter", "page_meter", "set_statusbar", "set_help_context"
+ ].forEach(function(k) { content_params[k] = xulG[k]; });
+
top_pane.set_iframe(
url,
- {},
- {
- 'set_tab_name' : function(n) {
- if (typeof window.xulG == 'object' && typeof window.xulG.set_tab_name == 'function') {
- try { window.xulG.set_tab_name(document.getElementById('offlineStrings').getFormattedString("cat.bib_record", [n])); } catch(E) { alert(E); }
- } else {
- dump('no set_tab_name\n');
- }
- }
- }
+ {},
+ content_params
);
}
JSAN.use('util.error'); error = new util.error();
JSAN.use('util.network'); var network = new util.network();
- var acn_id = network.simple_request(
+ var acn_blob = network.simple_request(
'FM_ACN_FIND_OR_CREATE',
[ ses(), cn_label, doc_id, ses('ws_ou') ]
);
- if (typeof acn_id.ilsevent != 'undefined') {
- error.standard_unexpected_error_alert('Error in chrome/content/cat/opac.js, cat.util.fast_item_add', acn_id);
+ if (typeof acn_blob.ilsevent != 'undefined') {
+ error.standard_unexpected_error_alert('Error in chrome/content/cat/opac.js, cat.util.fast_item_add', acn_blob);
return;
}
copy_obj.id( -1 );
copy_obj.isnew('1');
copy_obj.barcode( cp_barcode );
- copy_obj.call_number( acn_id );
+ copy_obj.call_number( acn_blob.acn_id );
copy_obj.circ_lib( ses('ws_ou') );
/* FIXME -- use constants */
copy_obj.deposit(0);
var title = document.getElementById('offlineStrings').getFormattedString('staff.circ.copy_status.add_volumes.title', [docid]);
+ var horizontal_interface = String( g.data.hash.aous['ui.cat.volume_copy_editor.horizontal'] ) == 'true';
+ var url = window.xulG.url_prefix( horizontal_interface ? urls.XUL_VOLUME_COPY_CREATOR_HORIZONTAL : urls.XUL_VOLUME_COPY_CREATOR );
var w = xulG.new_tab(
- window.xulG.url_prefix(urls.XUL_VOLUME_COPY_CREATOR),
+ url,
{ 'tab_name' : title },
{ 'doc_id' : docid, 'ou_ids' : [ ses('ws_ou') ] }
);
alert('Error in chrome/content/cat/opac.js, add_volumes(): ' + E);
}
}
+
+function manage_parts() {
+ try {
+ var title = document.getElementById('offlineStrings').getFormattedString('staff.cat.manage_parts.title', [docid]);
+ var loc = urls.XUL_BROWSER + "?url=" + window.escape(
+ window.xulG.url_prefix(urls.CONIFY_MANAGE_PARTS) + '?r=' + docid
+ );
+ var w = xulG.new_tab(
+ loc,
+ { 'tab_name' : title },
+ {}
+ );
+ } catch(E) {
+ alert('Error in chrome/content/cat/opac.js, manage_parts(): ' + E);
+ }
+}
+
<menuitem label="&staff.cat.copy_browser.holdings_maintenance.cmd_add_volumes.label;" accesskey="&staff.cat.copy_browser.holdings_maintenance.cmd_add_volumes.accesskey;" id="add_volumes" oncommand="add_volumes();"/>
<menuitem label="&staff.cat.opac.mark_for_hold_transfer.label;" accesskey="&staff.cat.opac.mark_for_hold_transfer.accesskey;" id="mark_for_hold_transfer" oncommand="mark_for_hold_transfer();"/>
<menuitem label="&staff.cat.opac.transfer_title_holds.label;" accesskey="&staff.cat.opac.transfer_title_holds.accesskey;" id="transfer_title_holds" oncommand="transfer_title_holds();"/>
+ <menuitem label="&staff.cat.opac.manage_parts.label;" accesskey="&staff.cat.opac.manage_parts.accesskey;" id="manage_parts" oncommand="manage_parts();"/>
<menuseparator/>
<menuitem label="&staff.cat.opac.bib_in_new_tab.label;" id="bib_in_new_tab" oncommand="bib_in_new_tab();"/>
<menuitem label="&staff.cat.opac.remove_me.label;" id="remove_me" oncommand="remove_me();"/>
'CHECKOUT_RENEW' : { 'app' : 'open-ils.circ', 'method' : 'open-ils.circ.renew' },
'CIRC_MODIFIER_LIST' : { 'app' : 'open-ils.circ', 'method' : 'open-ils.circ.circ_modifier.retrieve.all' },
'CLEAR_HOLD_SHELF' : { 'app' : 'open-ils.circ', 'method' : 'open-ils.circ.hold.clear_shelf.process', 'secure' : false },
- 'FM_ACN_RETRIEVE' : { 'app' : 'open-ils.search', 'method' : 'open-ils.search.callnumber.retrieve', 'secure' : false },
- 'FM_ACN_RETRIEVE.authoritative' : { 'app' : 'open-ils.search', 'method' : 'open-ils.search.callnumber.retrieve.authoritative', 'secure' : false },
+ 'FM_ACN_RETRIEVE' : { 'app' : 'open-ils.search', 'method' : 'open-ils.search.callnumber.fleshed.retrieve', 'secure' : false },
+ 'FM_ACN_RETRIEVE.authoritative' : { 'app' : 'open-ils.search', 'method' : 'open-ils.search.callnumber.fleshed.retrieve.authoritative', 'secure' : false },
'FM_ACN_TREE_UPDATE' : { 'app' : 'open-ils.cat', 'method' : 'open-ils.cat.asset.volume.fleshed.batch.update' },
'FM_ACN_TREE_LIST_RETRIEVE_VIA_RECORD_ID_AND_ORG_IDS' : { 'app' : 'open-ils.cat', 'method' : 'open-ils.cat.asset.copy_tree.retrieve', 'secure' : false },
'FM_ACN_TREE_LIST_RETRIEVE_VIA_RECORD_ID_AND_ORG_IDS.authoritative' : { 'app' : 'open-ils.cat', 'method' : 'open-ils.cat.asset.copy_tree.retrieve.authoritative', 'secure' : false },
'FM_ACN_TRANSFER' : { 'app' : 'open-ils.cat', 'method' : 'open-ils.cat.asset.volume.batch.transfer' },
- 'FM_ACN_FIND_OR_CREATE' : { 'app' : 'open-ils.cat', 'method' : 'open-ils.cat.call_number.find_or_create', 'secure' : false },
+ 'FM_ACN_FIND_OR_CREATE' : { 'app' : 'open-ils.cat', 'method' : 'open-ils.cat.call_number.find_or_create' },
+ 'FM_ACNC_RETRIEVE_VIA_PCRUD' : { 'app' : 'open-ils.pcrud', 'method' : 'open-ils.pcrud.search.acnc.atomic' },
+ 'FM_ACNP_RETRIEVE_VIA_PCRUD' : { 'app' : 'open-ils.pcrud', 'method' : 'open-ils.pcrud.search.acnp.atomic' },
+ 'FM_ACNS_RETRIEVE_VIA_PCRUD' : { 'app' : 'open-ils.pcrud', 'method' : 'open-ils.pcrud.search.acns.atomic' },
'FM_ACP_DETAILS' : { 'app' : 'open-ils.circ', 'method' : 'open-ils.circ.copy_details.retrieve' },
'FM_ACP_DETAILS_VIA_BARCODE' : { 'app' : 'open-ils.circ', 'method' : 'open-ils.circ.copy_details.retrieve.barcode' },
'FM_ACP_DETAILS_VIA_BARCODE.authoritative' : { 'app' : 'open-ils.circ', 'method' : 'open-ils.circ.copy_details.retrieve.barcode.authoritative' },
'XUL_USER_BUCKETS' : '/xul/server/patron/user_buckets.xul',
'XUL_VERIFY_CREDENTIALS' : '/xul/server/main/verify_credentials.xul',
'XUL_VOLUME_BUCKETS' : '/xul/server/cat/volume_buckets.xul',
- 'XUL_VOLUME_COPY_CREATOR' : '/xul/server/cat/volume_copy_creator.xul',
+ 'XUL_VOLUME_COPY_CREATOR' : '/xul/server/cat/volume_copy_editor.xul',
+ 'XUL_VOLUME_COPY_CREATOR_HORIZONTAL' : '/xul/server/cat/volume_copy_editor_horiz.xul',
+ 'XUL_VOLUME_COPY_CREATOR_ORIGINAL' : '/xul/server/cat/volume_copy_creator.xul',
'XUL_VOLUME_EDITOR' : '/xul/server/cat/volume_editor.xul',
'XUL_WORK_LOG' : '/xul/server/admin/work_log.xul',
'XUL_WORKSTATION_INFO' : '/xul/server/main/ws_info.xul',
'TEST_HTML' : '/xul/server/main/test.html',
'TEST_XUL' : '/xul/server/main/test.xul',
'CONIFY' : '/conify/' + LOCALE + '/global',
+ 'CONIFY_MANAGE_PARTS' : '/eg/conify/global/biblio/monograph_part',
'EG_WEB_BASE' : '/eg',
'XUL_LOCAL_ADMIN_BASE' : '/xul/server/admin',
'XUL_REPORTS' : '/reports/oils_rpt.xhtml',
['oncommand'],
function() { open_eg_web_page('conify/global/config/record_attr_definition'); }
],
- 'cmd_server_admin_coded_value_map' : [
+ 'cmd_server_admin_acn_prefix' : [
['oncommand'],
- function() { open_eg_web_page('conify/global/config/coded_value_map'); }
+ function() { open_eg_web_page('conify/global/config/acn_prefix'); }
+ ],
+ 'cmd_server_admin_acn_suffix' : [
+ ['oncommand'],
+ function() { open_eg_web_page('conify/global/config/acn_suffix'); }
],
'cmd_server_admin_billing_type' : [
['oncommand'],
},
'volume_item_creator' : function(params) {
var obj = this;
+ var horizontal_interface = String( obj.data.hash.aous['ui.cat.volume_copy_editor.horizontal'] ) == 'true';
+ var url = obj.url_prefix( horizontal_interface ? urls.XUL_VOLUME_COPY_CREATOR_HORIZONTAL : urls.XUL_VOLUME_COPY_CREATOR );
var w = obj.new_tab(
- obj.url_prefix(urls.XUL_VOLUME_COPY_CREATOR),
+ url,
{ 'tab_name' : document.getElementById('offlineStrings').getString('staff.cat.create_or_rebarcode_items') },
params
);
<command id="cmd_server_admin_marc_code"/>
<command id="cmd_server_admin_coded_value_map"/>
<command id="cmd_server_admin_billing_type"/>
+ <command id="cmd_server_admin_acn_prefix"/>
+ <command id="cmd_server_admin_acn_suffix"/>
<command id="cmd_server_admin_acq_invoice_item_type"/>
<command id="cmd_server_admin_acq_invoice_payment_method"/>
<command id="cmd_server_admin_acq_cancel_reason"/>
<menuitem label="&staff.main.menu.admin.server_admin.conify.grp_tree.label;" command="cmd_server_admin_grp_tree"/>
<menuitem label="&staff.main.menu.admin.server_admin.conify.perm_list.label;" command="cmd_server_admin_perm_list"/>
<menuitem label="&staff.main.menu.admin.server_admin.conify.copy_status.label;" command="cmd_server_admin_copy_status"/>
+ <menuitem label="&staff.main.menu.admin.server_admin.conify.acn_prefix.label;" command="cmd_server_admin_acn_prefix"/>
+ <menuitem label="&staff.main.menu.admin.server_admin.conify.acn_suffix.label;" command="cmd_server_admin_acn_suffix"/>
<menuitem label="&staff.main.menu.admin.server_admin.conify.marc_record_attrs.label;" command="cmd_server_admin_marc_code"/>
<menuitem label="&staff.main.menu.admin.server_admin.conify.coded_value_maps.label;" command="cmd_server_admin_coded_value_map"/>
<menuitem label="&staff.main.menu.admin.server_admin.conify.billing_type.label;" command="cmd_server_admin_billing_type"/>
'lock_reload' : false, // as opposed to lock 'n load :)
+ 'back_button_clicked' : false,
+ 'from_back' : false,
+
'init' : function( params ) {
try {
try {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var n = obj.getWebNavigation();
- if (n.canGoBack) n.goBack();
+ if (n.canGoBack) {
+ obj.back_button_clicked = true;
+ n.goBack();
+ }
} catch(E) {
var err = 'cmd_back: ' + E;
obj.error.sdump('D_ERROR',err);
cw.IAMXUL = true;
cw.XUL_BUILD_ID = '/xul/server/'.split(/\//)[2];
cw.xulG = obj.passthru_content_params || {};
+ cw.xulG.fromBack = obj.from_back;
if (!cw.xulG.set_tab) { cw.xulG.set_tab = function(a,b,c) { return window.xulG.set_tab(a,b,c); }; }
if (!cw.xulG.new_tab) { cw.xulG.new_tab = function(a,b,c) { return window.xulG.new_tab(a,b,c); }; }
if (!cw.xulG.close_tab) { cw.xulG.close_tab = function(a) { return window.xulG.close_tab(a); }; }
if (stateFlags & nsIWebProgressListener.STATE_IS_DOCUMENT) {
s += ('\tSTATE_IS_DOCUMENT\n');
if( stateFlags & nsIWebProgressListener.STATE_STOP ) {
+ var alert_string = 'document has stopped: ' + new Date() + '\n'; dump(alert_string);
obj.push_variables(); obj.updateNavButtons();
if (typeof obj.on_url_load == 'function') {
try {
}
if (stateFlags & nsIWebProgressListener.STATE_START) {
s += ('\tSTATE_START\n');
+ obj.from_back = obj.back_button_clicked;
+ obj.back_button_clicked = false;
}
if (stateFlags & nsIWebProgressListener.STATE_REDIRECTING) {
s += ('\tSTATE_REDIRECTING\n');
'init' : function (params) {
var obj = this;
+ obj.scratch_data = {};
JSAN.use('util.widgets');
if (typeof params.map_row_to_column == 'function') {
- label = params.map_row_to_column(params.row,this.columns[i]);
+ label = params.map_row_to_column(params.row,this.columns[i],this.scratch_data);
} else if (typeof this.map_row_to_column == 'function') {
- label = this.map_row_to_column(params.row,this.columns[i]);
+ label = this.map_row_to_column(params.row,this.columns[i],this.scratch_data);
}
if (this.columns[i].type == 'checkbox') { treecell.setAttribute('value',label); } else { treecell.setAttribute('label',label ? label : ''); }
if (typeof params.map_row_to_columns == 'function') {
- labels = params.map_row_to_columns(params.row,this.columns);
+ labels = params.map_row_to_columns(params.row,this.columns,this.scratch_data);
} else if (typeof this.map_row_to_columns == 'function') {
- labels = this.map_row_to_columns(params.row,this.columns);
+ labels = this.map_row_to_columns(params.row,this.columns,this.scratch_data);
}
for (var i = 0; i < labels.length; i++) {
var value = '';
if (typeof params.map_row_to_column == 'function') {
- value = params.map_row_to_column(params.row,this.columns[i]);
+ value = params.map_row_to_column(params.row,this.columns[i],this.scratch_data);
} else {
if (typeof this.map_row_to_column == 'function') {
- value = this.map_row_to_column(params.row,this.columns[i]);
+ value = this.map_row_to_column(params.row,this.columns[i],this.scratch_data);
}
}
if (typeof value == 'string' || typeof value == 'number') {
},
// Default for the map_row_to_columns function for .init
'std_map_row_to_columns' : function(error_value) {
- return function(row,cols) {
+ return function(row,cols,scratch) {
// row contains { 'my' : { 'acp' : {}, 'circ' : {}, 'mvr' : {} } }
// cols contains all of the objects listed above in columns
+ // scratch is a temporary space shared by all cells/rows (or just per row if not explicitly passed in)
+ if (!scratch) { scratch = {}; }
var obj = {};
JSAN.use('util.error'); obj.error = new util.error();
try {
for (var i = 0; i < cols.length; i++) {
switch (typeof cols[i].render) {
- case 'function': try { values[i] = cols[i].render(my); } catch(E) { values[i] = error_value; obj.error.sdump('D_COLUMN_RENDER_ERROR',E); } break;
+ case 'function': try { values[i] = cols[i].render(my,scratch); } catch(E) { values[i] = error_value; obj.error.sdump('D_COLUMN_RENDER_ERROR',E); } break;
case 'string' : cmd += 'try { ' + cols[i].render + '; values['+i+'] = v; } catch(E) { values['+i+'] = error_value; }'; break;
default: cmd += 'values['+i+'] = "??? '+(typeof cols[i].render)+'"; ';
}
menuitem.setAttribute('disabled','true');
}
}
- menulist.setAttribute('value',dvalue);
+ if (typeof dvalue != 'undefined') {
+ menulist.setAttribute('value',dvalue);
+ }
return menulist;
}
}
}
-util.widgets.apply_vertical_tab_on_enter_handler = function(node,onfailure) {
+util.widgets.apply_vertical_tab_on_enter_handler = function(node,onfailure,no_enter_func) {
try {
node.addEventListener(
'keypress',
ev.preventDefault(); ev.stopPropagation();
return true;
} else {
+ dump('keypress: attempting onfailure\n');
if (typeof onfailure == 'function') return onfailure(ev);
return false;
}
+ } else {
+ if (typeof no_enter_func == 'function') {
+ no_enter_func(ev);
+ }
}
},
false
staff.cat.util.copy_editor.view=View
staff.circ.copy_status.add_volumes.perm_failure=You do not have permission to add volumes to the workstation library.
staff.circ.copy_status.add_volumes.title=Add Volume/Item for Record # %1$s
+staff.cat.manage_parts.title=Manage Parts for Record # %1$s
staff.cat.z3950.marked_record_for_overlay_indicator.tcn.label=Record with TCN %1$s marked for overlay.
staff.cat.z3950.marked_record_for_overlay_indicator.record_id.label=Record with ID %1$s marked for overlay.
staff.cat.opac.marked_record_for_hold_transfer_indicator.tcn.label=Record with TCN %1$s marked for title hold transfer.
JSAN.use('util.error'); g.error = new util.error();
g.error.sdump('D_TRACE','my_init() for cat_bib_brief.xul');
- JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
+ JSAN.use('OpenILS.data'); g.data = new OpenILS.data(); g.data.init({'via':'stash'});
docid = xul_param('docid');
var key = location.pathname + location.search + location.hash;
- if (!docid && typeof data.modal_xulG_stack != 'undefined' && typeof data.modal_xulG_stack[key] != 'undefined') {
- var xulG = data.modal_xulG_stack[key][ data.modal_xulG_stack[key].length - 1 ];
+ if (!docid && typeof g.data.modal_xulG_stack != 'undefined' && typeof g.data.modal_xulG_stack[key] != 'undefined') {
+ var xulG = g.data.modal_xulG_stack[key][ g.data.modal_xulG_stack[key].length - 1 ];
if (typeof xulG == 'object') {
docid = xulG.docid;
}
if (docid > -1) {
- data.last_record = docid; data.stash('last_record');
+ g.data.last_record = docid; g.data.stash('last_record');
g.network.simple_request(
'MODS_SLIM_RECORD_RETRIEVE.authoritative',
}
}
+function unhide_add_volumes_button() {
+ if (xulG && typeof xulG == 'object' && typeof xulG['new_tab'] == 'function') {
+ document.getElementById('add_volumes').hidden = false;
+ document.getElementById('add_volumes_left_paren').hidden = false;
+ document.getElementById('add_volumes_right_paren').hidden = false;
+ }
+}
+
function view_marc() {
try {
JSAN.use('util.window'); var win = new util.window();
}
}
+function add_volumes() {
+ try {
+ var edit = 0;
+ try {
+ edit = g.network.request(
+ api.PERM_MULTI_ORG_CHECK.app,
+ api.PERM_MULTI_ORG_CHECK.method,
+ [
+ ses(),
+ ses('staff_id'),
+ [ ses('ws_ou') ],
+ [ 'CREATE_VOLUME', 'CREATE_COPY' ]
+ ]
+ ).length == 0 ? 1 : 0;
+ } catch(E) {
+ g.error.sdump('D_ERROR','batch permission check: ' + E);
+ }
+ if (edit==0) {
+ alert(document.getElementById('offlineStrings').getString('staff.circ.copy_status.add_volumes.perm_failure'));
+ return; // no read-only view for this interface
+ }
+
+ var title = document.getElementById('offlineStrings').getFormattedString('staff.circ.copy_status.add_volumes.title', [docid]);
+
+ var horizontal_interface = String( g.data.hash.aous['ui.cat.volume_copy_editor.horizontal'] ) == 'true';
+ var url = window.xulG.url_prefix( horizontal_interface ? urls.XUL_VOLUME_COPY_CREATOR_HORIZONTAL : urls.XUL_VOLUME_COPY_CREATOR );
+ var w = xulG.new_tab(
+ url,
+ { 'tab_name' : title },
+ { 'doc_id' : docid, 'ou_ids' : [ ses('ws_ou') ] }
+ );
+ } catch(E) {
+ alert('Error in server/cat/bib_brief.js, add_volumes(): ' + E);
+ }
+}
<?xul-overlay href="/xul/server/cat/bib_brief_overlay.xul"?>
<window id="cat_bib_brief_win"
- onload="try { my_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
+ onload="try { my_init(); font_helper(); persist_helper(); unhide_add_volumes_button(); } catch(E) { alert(E); }"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
<messagecatalog id="circStrings" src="/xul/server/locale/<!--#echo var='locale'-->/circ.properties"/>
<groupbox id="groupbox" flex="1">
- <caption id="caption"><label value="&staff.cat.bib_brief.record_summary;"/>(<label value="&staff.cat.bib_brief.view_marc;" class="click_link" onclick="view_marc();"/>)</caption>
+ <caption id="caption">
+ <label value="&staff.cat.bib_brief.record_summary;"/>
+ <label id="add_volumes_left_paren" value="(" hidden="true"/>
+ <label id="add_volumes" value="&staff.cat.bib_brief.add_volumes;" class="click_link" onclick="add_volumes();" hidden="true"/>
+ <label id="add_volumes_right_paren" value=")" hidden="true"/>
+ (<label value="&staff.cat.bib_brief.view_marc;" class="click_link" onclick="view_marc();"/>)
+ </caption>
<grid id="bib_brief_grid" />
</groupbox>
var title = document.getElementById('catStrings').getString('staff.cat.copy_browser.add_item.title');
+ var horizontal_interface = String( obj.data.hash.aous['ui.cat.volume_copy_editor.horizontal'] ) == 'true';
+ var url = window.xulG.url_prefix( horizontal_interface ? urls.XUL_VOLUME_COPY_CREATOR_HORIZONTAL : urls.XUL_VOLUME_COPY_CREATOR );
var w = xulG.new_tab(
- window.xulG.url_prefix(urls.XUL_VOLUME_COPY_CREATOR),
+ url,
{ 'tab_name' : title },
{
'doc_id' : obj.docid,
'ou_ids' : list,
'copy_shortcut' : copy_shortcut,
- 'refresh' : function() { obj.refresh_list(); }
+ 'onrefresh' : function() { obj.refresh_list(); }
}
);
} catch(E) {
}
}
],
- 'cmd_replace_barcode' : [
+ 'cmd_edit_items' : [
['command'],
function() {
try {
xulG.volume_item_creator( {'existing_copies':list, 'onrefresh' : function() { obj.refresh_list(); } } );
} catch(E) {
- obj.error.standard_unexpected_error_alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.replace_barcode.error'),E);
+ obj.error.standard_unexpected_error_alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.edit_items.error'),E);
obj.refresh_list();
}
}
],
- 'cmd_edit_items' : [
+ 'old_cmd_edit_items' : [
['command'],
function() {
try {
var title = document.getElementById('catStrings').getString('staff.cat.copy_browser.add_volume.title');
+ var horizontal_interface = String( obj.data.hash.aous['ui.cat.volume_copy_editor.horizontal'] ) == 'true';
+ var url = window.xulG.url_prefix( horizontal_interface ? urls.XUL_VOLUME_COPY_CREATOR_HORIZONTAL : urls.XUL_VOLUME_COPY_CREATOR );
var w = xulG.new_tab(
- window.xulG.url_prefix(urls.XUL_VOLUME_COPY_CREATOR),
+ url,
{ 'tab_name' : title },
- { 'doc_id' : obj.docid, 'ou_ids' : list, 'refresh' : function() { obj.refresh_list(); } }
+ { 'doc_id' : obj.docid, 'ou_ids' : list, 'onrefresh' : function() { obj.refresh_list(); } }
);
} catch(E) {
}
if (robj.ilsevent != 0) throw(robj);
}
- alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.delete_volume.success'));
obj.refresh_list();
}
} catch(E) {
var data = {
'row' : {
'my' : {
+ 'doc_id' : obj.docid,
'aou' : obj.data.hash.aou[ acn_tree.owning_lib() ],
'acn' : acn_tree,
'acp' : acp_item,
'circ_lib' : { 'hidden' : false },
'owning_lib' : { 'hidden' : false },
'call_number' : { 'hidden' : false },
+ 'parts' : { 'hidden' : false },
'due_date' : { 'hidden' : false },
'acp_status' : { 'hidden' : false },
},
'due_date',
'owning_lib',
'circ_lib',
+ 'label_class',
+ 'prefix',
'call_number',
+ 'suffix',
'copy_number',
+ 'parts',
'location',
'barcode',
'loan_duration',
obj.controller.view.cmd_add_items.setAttribute('disabled','true');
obj.controller.view.cmd_add_items_to_buckets.setAttribute('disabled','true');
obj.controller.view.cmd_edit_items.setAttribute('disabled','true');
- obj.controller.view.cmd_replace_barcode.setAttribute('disabled','true');
obj.controller.view.cmd_delete_items.setAttribute('disabled','true');
obj.controller.view.cmd_print_spine_labels.setAttribute('disabled','true');
obj.controller.view.cmd_add_volumes.setAttribute('disabled','true');
obj.controller.view.sel_mark_items_missing.setAttribute('disabled','false');
obj.controller.view.cmd_add_items_to_buckets.setAttribute('disabled','false');
obj.controller.view.cmd_edit_items.setAttribute('disabled','false');
- obj.controller.view.cmd_replace_barcode.setAttribute('disabled','false');
obj.controller.view.cmd_delete_items.setAttribute('disabled','false');
obj.controller.view.cmd_print_spine_labels.setAttribute('disabled','false');
obj.controller.view.cmd_transfer_items.setAttribute('disabled','false');
<command id="cmd_add_items"/>
<command id="cmd_add_items_to_buckets"/>
<command id="cmd_edit_items"/>
- <command id="cmd_replace_barcode"/>
<command id="cmd_delete_items"/>
<command id="cmd_transfer_items"/>
<command id="cmd_print_spine_labels"/>
<menuitem command="sel_mark_items_missing" label="&staff.cat.copy_browser.actions.sel_mark_items_missing.label;" accesskey="&staff.cat.copy_browser.actions.sel_mark_items_missing.accesskey;"/>
<menuseparator/>
<menuitem command="cmd_print_spine_labels" label="&staff.cat.copy_browser.actions.cmd_print_spine_labels.label;" accesskey="&staff.cat.copy_browser.actions.cmd_print_spine_labels.accesskey;"/>
- <menuitem command="cmd_replace_barcode" label="&staff.cat.copy_browser.actions.cmd_replace_barcode.label;" accesskey=""/>
<menuitem command="save_columns" label="&staff.cat.copy_browser.actions.save_columns.label;"/>
<menuitem command="cmd_refresh_list" label="&staff.cat.copy_browser.actions.cmd_refresh_list.label;" accesskey="&staff.cat.copy_browser.actions.cmd_refresh_list.accesskey;"/>
</popup>
<label value="&staff.cat.copy_browser.holdings_maintenance.depth_filter_menu;" />
<hbox id="x_depth_menu"/>
<spacer flex="1"/>
- <label value="&staff.cat.copy_browser.holdings_maintenance.consortial_total;"/><label id="consortial_total"/>
- <label value="&staff.cat.copy_browser.holdings_maintenance.consortial_available;"/><label id="consortial_available"/>
</hbox>
<hbox>
<checkbox id="show_acns" label="&staff.cat.copy_browser.holdings_maintenance.show_acns;" />
<button label="Show All Libs" command="cmd_show_all_libs" accesskey=""/>
-->
<spacer flex="1"/>
+ <label value="&staff.cat.copy_browser.holdings_maintenance.consortial_total;"/><label id="consortial_total"/>
+ <label value="&staff.cat.copy_browser.holdings_maintenance.consortial_available;"/><label id="consortial_available"/>
<menubar>
<menu label="&staff.cat.copy_browser.holdings_maintenance.actions.label;" accesskey="&staff.cat.copy_browser.holdings_maintenance.actions.accesskey;">
<menupopup>
<menuitem command="sel_mark_items_missing" label="&staff.cat.copy_browser.holdings_maintenance.sel_mark_items_missing.label;" accesskey="&staff.cat.copy_browser.holdings_maintenance.sel_mark_items_missing.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=""/>
<menuitem command="save_columns" label="&staff.cat.copy_browser.holdings_maintenance.save_columns.label;"/>
<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;"/>
</menupopup>
var g = {};
g.map_acn = {};
-var xulG = {};
-
function $(id) { return document.getElementById(id); }
function my_init() {
JSAN.use('OpenILS.data'); g.data = new OpenILS.data(); g.data.init({'via':'stash'});
JSAN.use('util.network'); g.network = new util.network();
+ if (xulG.unified_interface) {
+ $('non_unified_buttons').hidden = true;
+ }
+
g.docid = xul_param('docid',{'modal_xulG':true});
g.handle_update = xul_param('handle_update',{'modal_xulG':true});
if (xul_param('edit',{'modal_xulG':true}) == '1') {
- // Editor desired, but let's check permissions
- g.edit = false;
+ g.edit = true;
- try {
- var check = g.network.simple_request(
- 'PERM_MULTI_ORG_CHECK',
- [
- ses(),
- g.data.list.au[0].id(),
- util.functional.map_list(
- g.copies,
- function (o) {
- var lib;
- var cn_id = o.call_number();
- if (cn_id == -1) {
- lib = o.circ_lib(); // base perms on circ_lib instead of owning_lib if pre-cat
- } else {
- if (! g.map_acn[ cn_id ]) {
- var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
- if (typeof req.ilsevent == 'undefined') {
- g.map_acn[ cn_id ] = req;
- lib = g.map_acn[ cn_id ].owning_lib();
+ if (g.copies.length > 0) { // When loaded in the unified interface, there may be no copies yet (from the volum/item creator)
+
+ // Editor desired, but let's check permissions
+ g.edit = false;
+
+ try {
+ var check = g.network.simple_request(
+ 'PERM_MULTI_ORG_CHECK',
+ [
+ ses(),
+ g.data.list.au[0].id(),
+ util.functional.map_list(
+ g.copies,
+ function (o) {
+ var lib;
+ var cn_id = o.call_number();
+ if (cn_id == -1) {
+ lib = o.circ_lib(); // base perms on circ_lib instead of owning_lib if pre-cat
+ } else {
+ if (! g.map_acn[ cn_id ]) {
+ var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
+ if (typeof req.ilsevent == 'undefined') {
+ g.map_acn[ cn_id ] = req;
+ lib = g.map_acn[ cn_id ].owning_lib();
+ } else {
+ lib = o.circ_lib();
+ }
} else {
- lib = o.circ_lib();
+ lib = g.map_acn[ cn_id ].owning_lib();
}
- } else {
- lib = g.map_acn[ cn_id ].owning_lib();
}
+ return typeof lib == 'object' ? lib.id() : lib;
}
- return typeof lib == 'object' ? lib.id() : lib;
- }
- ),
- g.copies.length == 1 ? [ 'UPDATE_COPY' ] : [ 'UPDATE_COPY', 'UPDATE_BATCH_COPY' ]
- ]
- );
- g.edit = check.length == 0;
- } catch(E) {
- g.error.standard_unexpected_error_alert('batch permission check',E);
+ ),
+ g.copies.length == 1 ? [ 'UPDATE_COPY' ] : [ 'UPDATE_COPY', 'UPDATE_BATCH_COPY' ]
+ ]
+ );
+ g.edit = check.length == 0;
+ } catch(E) {
+ g.error.standard_unexpected_error_alert('batch permission check',E);
+ }
+
}
if (g.edit) {
} else {
$('top_nav').setAttribute('hidden','true');
}
+
} else {
$('top_nav').setAttribute('hidden','true');
}
g.render();
g.check_for_unmet_required_fields();
+ if (xulG.unified_interface) {
+ xulG.refresh_copy_editor = function() {
+ try {
+ g.copies = xulG.copies;
+ g.original_copies = js2JSON( g.copies );
+ for (var i = 0; i < g.applied_templates.length; i++) {
+ g._apply_template( g.applied_templates[i] );
+ }
+ g.summarize( g.copies );
+ g.render();
+ g.check_for_unmet_required_fields();
+ } catch(E) {
+ alert('Error in copy_editor.js, xulG.refresh_copy_editor(): ' + E);
+ }
+ };
+ xulG.unlock_copy_editor = function() {
+ oils_unlock_page();
+ };
+ xulG.notify_of_templatable_field_change = function(id,v) {
+ g.changed[ 'volume_copy_creator.'+id ] = { 'type' : 'volume_copy_creator', 'field' : id, 'value' : v };
+ }
+ }
+
} catch(E) {
var err_msg = $("commonStrings").getFormattedString('common.exception', ['cat/copy_editor.js', E]);
try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); dump(js2JSON(E)); }
function() { g.copy_editor_prefs[ 'template_menu' ] = { 'value' : g.template_menu.value }; g.save_attributes(); },
false
);
+
+ if (xulG.unified_interface) {
+ if (typeof xulG.update_unified_template_list == 'function') {
+ xulG.update_unified_template_list(list);
+ // functions the unified wrapper should use to let the item attribute editor do the heavy lifting for templates
+ xulG.update_item_editor_template_selection = function(new_value) {
+ g.template_menu.value = new_value;
+ g.copy_editor_prefs[ 'template_menu' ] = { 'value' : g.template_menu.value };
+ g.save_attributes();
+ }
+ xulG.item_editor_apply_template = function() { g.apply_template(); };
+ xulG.item_editor_delete_template = function() { g.delete_template(); };
+ xulG.item_editor_save_template = function() { g.save_template(); };
+ xulG.item_editor_import_templates = function() { g.import_templates(); };
+ xulG.item_editor_export_templates = function() { g.export_templates(); };
+ xulG.item_editor_reset = function() { g.reset(); };
+ }
+ }
+
} catch(E) {
g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.retrieve_templates.error'), E);
}
/******************************************************************************************************/
/* Apply Template */
+g.applied_templates = [];
+
g.apply_template = function() {
try {
var name = g.template_menu.value;
if (g.templates[ name ] != 'undefined') {
+ g.applied_templates.push( name );
+ g._apply_template(name);
+ g.summarize( g.copies );
+ g.render();
+ g.check_for_unmet_required_fields();
+ }
+ } catch(E) {
+ g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.apply_templates.error'), E);
+ }
+}
+
+g._apply_template = function(name) {
+ try {
+ if (g.templates[ name ] != 'undefined') {
var template = g.templates[ name ];
for (var i in template) {
g.changed[ i ] = template[ i ];
case 'owning_lib' :
g.apply_owning_lib(template[i].value);
break;
+ case 'volume_copy_creator' :
+ if (xulG.unified_interface) {
+ xulG.apply_template_to_batch(template[i].field,template[i].value);
+ }
+ break;
}
}
- g.summarize( g.copies );
- g.render();
- g.check_for_unmet_required_fields();
}
} catch(E) {
- g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.apply_templates.error'), E);
+ alert('Error in copy_editor.js, g._apply_template('+name+'): ' + E);
}
}
/* Restore backup copies */
g.reset = function() {
+ g.applied_templates = [];
g.changed = {};
g.copies = JSON2js( g.original_copies );
g.summarize( g.copies );
g.render();
g.check_for_unmet_required_fields();
oils_unlock_page();
+ if (xulG.unified_interface) {
+ xulG.reset_batch_menus();
+ }
}
/******************************************************************************************************/
g.apply_owning_lib = function(ou_id) {
g.error.sdump('D_TRACE','ou_id = ' + ou_id + '\n');
+ // but don't allow this when bundled with the volume/copy creator UI, or if we're editing pre-cats
+ if (! g.safe_to_change_owning_lib() ) { return; }
for (var i = 0; i < g.copies.length; i++) {
var copy = g.copies[i];
try {
g.map_acn[copy.call_number()] = volume;
}
var old_volume = g.map_acn[copy.call_number()];
- var acn_id = g.network.simple_request(
+ var acn_blob = g.network.simple_request(
'FM_ACN_FIND_OR_CREATE',
- [ses(),old_volume.label(),old_volume.record(),ou_id]
+ [ses(),old_volume.label(),old_volume.record(),ou_id,old_volume.prefix(),old_volume.suffix(),old_volume.label_class()]
);
- if (typeof acn_id.ilsevent != 'undefined') {
- g.error.standard_unexpected_error_alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_owning_lib.call_number.error', [copy.barcode()]), acn_id);
+ if (typeof acn_blob.ilsevent != 'undefined') {
+ g.error.standard_unexpected_error_alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_owning_lib.call_number.error', [copy.barcode()]), acn_blob);
continue;
}
- copy.call_number(acn_id);
+ copy.call_number(acn_blob.acn_id);
copy.ischanged('1');
} catch(E) {
g.error.standard_unexpected_error_alert('apply_stat_cat',E);
}
/******************************************************************************************************/
-/* This returns true if none of the copies being edited are pre-cats */
+/* This returns false if any of the copies being edited are pre-cats, or if we're embedded in the unified volume/copy UI */
g.safe_to_change_owning_lib = function() {
try {
+ if (xulG.unified_interface) { return false; }
var safe = true;
for (var i = 0; i < g.copies.length; i++) {
var cn = g.copies[i].call_number();
<window id="cat_copy_editor_win"
onload="try { my_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
- width="800" height="580" oils_persist="width height"
title="&staff.cat.copy_editor.window.label;"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<caption id="caption" label="&staff.cat.copy_editor.groupbox1.label;"/>
<hbox id="top_nav">
- <hbox style="background: grey">
+ <hbox id="template_bar" style="background: grey" flex="1">
<vbox><spacer flex="1"/><label value="&staff.cat.copy_editor.templates.label;" style="font-weight: bold"/><spacer flex="1"/></vbox>
<hbox id="template_placeholder"/>
<button id="apply_template" label="&staff.cat.copy_editor.templates.apply_template.label;" accesskey="&staff.cat.copy_editor.templates.apply_template.accesskey;" oncommand="g.apply_template()"/>
<button id="import_templates" label="&staff.cat.copy_editor.templates.import_template.label;" oncommand="g.import_templates()"/>
<button id="export_templates" label="&staff.cat.copy_editor.templates.export_template.label;" oncommand="g.export_templates()"/>
<button id="save_template" label="&staff.cat.copy_editor.templates.save_template.label;" oncommand="g.save_template()"/>
+ <spacer flex="1"/>
+ <button label="&staff.cat.copy_editor.templates.reset.label;" accesskey="&staff.cat.copy_editor.templates.reset.accesskey;" oncommand="g.reset()"/>
</hbox>
- <spacer flex="1"/>
- <button label="&staff.cat.copy_editor.templates.reset.label;" accesskey="&staff.cat.copy_editor.templates.reset.accesskey;" oncommand="g.reset()"/>
</hbox>
<hbox flex="1" style="overflow: scroll">
<hbox id="nav">
<spacer flex="1"/>
<button id="copy_notes" label="&staff.cat.copy_editor.copy_notes.label;" accesskey="&staff.cat.copy_editor.copy_notes.accesskey;" oncommand="g.copy_notes();"/>
- <button id="save" label="&staff.cat.copy_editor.save.label;" hidden="true" accesskey="&staff.cat.copy_editor.save.accesskey;" oncommand="g.stash_and_close();"/>
- <button id="cancel" label="&staff.cat.copy_editor.cancel.label;" accesskey="&staff.cat.copy_editor.cancel.accesskey;" oncommand="JSAN.use('util.widgets'); util.widgets.dispatch('close',window);"/>
+ <hbox id="non_unified_buttons">
+ <button id="save" label="&staff.cat.copy_editor.save.label;" hidden="true" accesskey="&staff.cat.copy_editor.save.accesskey;" oncommand="g.stash_and_close();"/>
+ <button id="cancel" label="&staff.cat.copy_editor.cancel.label;" accesskey="&staff.cat.copy_editor.cancel.accesskey;" oncommand="JSAN.use('util.widgets'); util.widgets.dispatch('close',window);"/>
+ </hbox>
</hbox>
<spacer/>
var record = g.network.simple_request('MODS_SLIM_RECORD_RETRIEVE.authoritative', [ volume.record() ]);
volume.record( record );
- /* Jam the prefixes and suffixes into the volume object */
- volume.prefix = label_prefix;
- volume.suffix = label_suffix;
+ /* The volume object has native prefix and suffixes now, so affix the ones coming from copy locations */
+ var temp_prefix = label_prefix + ' ' + (typeof volume.prefix() == 'object' ? volume.prefix().label() : volume.prefix());
+ var temp_suffix = (typeof volume.suffix() == 'object' ? volume.suffix().label() : volume.suffix()) + ' ' + label_suffix;
+
+ /* And assume that leading and trailing spaces can be trimmed */
+ temp_prefix = temp_prefix.replace(/\s+$/,'').replace(/^\s+/,'');
+ temp_suffix = temp_suffix.replace(/\s+$/,'').replace(/^\s+/,'');
+
+ volume.prefix( temp_prefix );
+ volume.suffix( temp_suffix );
g.volumes[ volume.id() ] = volume;
}
/* Only add the prefixes and suffixes once */
if (!override || volume.id() != override.acn) {
- if (volume.prefix) {
- callnum = volume.prefix + ' ' + callnum;
+ if (volume.prefix()) {
+ callnum = volume.prefix() + ' ' + callnum;
}
- if (volume.suffix) {
- callnum += ' ' + volume.suffix;
+ if (volume.suffix()) {
+ callnum += ' ' + volume.suffix();
}
}
JSAN.use('util.error'); error = new util.error();
JSAN.use('util.network'); var network = new util.network();
- var acn_id = network.simple_request(
+ var acn_blob = network.simple_request(
'FM_ACN_FIND_OR_CREATE',
[ ses(), cn_label, doc_id, ses('ws_ou') ]
);
- if (typeof acn_id.ilsevent != 'undefined') {
- error.standard_unexpected_error_alert($("catStrings").getFormattedString('staff.cat.volume_copy_creator.stash_and_close.problem_with_volume', [cn]), acn_id);
+ if (typeof acn_blob.ilsevent != 'undefined') {
+ error.standard_unexpected_error_alert($("catStrings").getFormattedString('staff.cat.volume_copy_creator.stash_and_close.problem_with_volume', [cn]), acn_blob);
return;
}
copy_obj.id( -1 );
copy_obj.isnew('1');
copy_obj.barcode( cp_barcode );
- copy_obj.call_number( acn_id );
+ copy_obj.call_number( acn_blob.acn_id );
copy_obj.circ_lib( ses('ws_ou') );
/* FIXME -- use constants */
copy_obj.deposit(0);
const g_max_copies_that_can_be_added_at_a_time_per_volume = 999;
+const rel_vert_pos_volume_count = 1;
+const rel_vert_pos_call_number_classification = 2;
+const rel_vert_pos_call_number_prefix = 3;
+const rel_vert_pos_call_number = 4;
+const rel_vert_pos_call_number_suffix = 5;
+const rel_vert_pos_copy_count = 6;
+const rel_vert_pos_barcode = 7;
+const rel_vert_pos_part = 8;
+const update_timer = 1000;
var g = {};
+g.use_defaults = true;
+g.acn_map = {}; // store retrieved acn objects here by id
function my_init() {
try {
g.error.sdump('D_TRACE','my_init() for cat/volume_copy_creator.xul');
JSAN.use('OpenILS.data'); g.data = new OpenILS.data(); g.data.init({'via':'stash'});
- JSAN.use('util.widgets'); JSAN.use('util.functional');
+ JSAN.use('util.widgets'); JSAN.use('util.functional'); JSAN.use('util.fm_utils');
JSAN.use('util.network'); g.network = new util.network();
g.refresh = xul_param('onrefresh');
+ if (xulG.unified_interface) {
+ $('non_unified_buttons').hidden = true;
+ xulG.reset_batch_menus = function() {
+ $('batch_class_menulist').value = false;
+ util.widgets.dispatch('command',$('batch_class_menulist'));
+ $('batch_prefix_menulist').value = false;
+ util.widgets.dispatch('command',$('batch_prefix_menulist'));
+ $('batch_suffix_menulist').value = false;
+ util.widgets.dispatch('command',$('batch_suffix_menulist'));
+ }
+ xulG.apply_template_to_batch = function(id,value) {
+ if (!isNaN(Number(value))) {
+ $(id).value = value;
+ util.widgets.dispatch('command',$(id));
+ }
+ setTimeout(
+ function() {
+ // TODO: Only apply batch to columns that haven't been adjusted manually?
+ util.widgets.dispatch('command',$('batch_button'));
+ },0
+ );
+ }
+ } else {
+ $('Create').hidden = true;
+ }
+
/***********************************************************************************************************/
/* Am I adding just copies or copies and volumes? Or am I rebarcoding existing copies? */
set_attr('EditThenCreate','accesskey','staff.cat.volume_copy_creator.edit_then_rebarcode.btn.accesskey');
set_attr('CreateWithDefaults','label','staff.cat.volume_copy_creator.rebarcode.btn.label');
set_attr('CreateWithDefaults','accesskey','staff.cat.volume_copy_creator.rebarcode.btn.accesskey');
+ set_attr('Create','label','staff.cat.volume_copy_creator.rebarcode.btn.label');
+ set_attr('Create','accesskey','staff.cat.volume_copy_creator.rebarcode.btn.accesskey');
} else {
set_attr('EditThenCreate','label','staff.cat.volume_copy_creator.edit_then_create.btn.label');
set_attr('EditThenCreate','accesskey','staff.cat.volume_copy_creator.edit_then_create.btn.accesskey');
set_attr('CreateWithDefaults','label','staff.cat.volume_copy_creator.create_with_defaults.btn.label');
set_attr('CreateWithDefaults','accesskey','staff.cat.volume_copy_creator.create_with_defaults.btn.accesskey');
+ set_attr('Create','label','staff.cat.volume_copy_creator.create.btn.label');
+ set_attr('Create','accesskey','staff.cat.volume_copy_creator.create.btn.accesskey');
}
//g.error.sdump('D_ERROR','location.href = ' + location.href + '\n\ncopy_short cut = ' + g.copy_shortcut + '\n\nou_ids = ' + xul_param('ou_ids'));
// Get the default callnumber classification scheme from OU settings
dojo.require('fieldmapper.OrgUtils');
- var label_class = g.data.hash.aous['cat.default_classification_scheme']; //fieldmapper.aou.fetchOrgSettingDefault(ses('ws_ou'), 'cat.default_classification_scheme');
+ //fieldmapper.aou.fetchOrgSettingDefault(ses('ws_ou'), 'cat.default_classification_scheme');
+ g.label_class = g.data.hash.aous['cat.default_classification_scheme'];
- // Assign a default value if none was returned
- if (!label_class) {
- label_class = 1;
+ // Assign a default value if none was returned
+ if (!g.label_class) {
+ g.label_class = g.data.list.acnc[0].id();
}
/***********************************************************************************************************/
- /* If we're passed existing_copies, rig up a copy_shortcut object to leverage existing code for rendering the volume labels, etc.
- * Also make a lookup object for existing copies keyed on org id and callnumber label, and another keyed on copy id. */
+ /* If we're passed existing_copies, rig up a copy_shortcut object to leverage existing code for rendering the volume labels, etc.
+ * Also make a lookup object for existing copies keyed on org id and callnumber composite key, and another keyed on copy id. */
- // g.org_label_existing_copy_map = { ou_id : { callnumber_label : [ copy1, copy2, ... ] }, ... }
+ // g.org_label_existing_copy_map = { ou_id : { callnumber_composite_key : [ copy1, copy2, ... ] }, ... }
g.org_label_existing_copy_map = {};
// g.id_copy_map = { acp_id : acp, ... }
g.id_copy_map = {};
g.copy_shortcut[ call_number.owning_lib() ] = {};
g.org_label_existing_copy_map[ call_number.owning_lib() ] = {};
}
- g.copy_shortcut[ call_number.owning_lib() ][ call_number.label() ] = call_number.id();
- if (! g.org_label_existing_copy_map[ call_number.owning_lib() ][ call_number.label() ]) {
- g.org_label_existing_copy_map[ call_number.owning_lib() ][ call_number.label() ] = [];
+ var acnc_id = call_number.label_class() ?
+ ( typeof call_number.label_class() == 'object' ? call_number.label_class().id() : call_number.label_class() )
+ : g.label_class;
+ var acnp_id = typeof call_number.prefix() == 'object' ? call_number.prefix().id() : call_number.prefix();
+ var acns_id = typeof call_number.suffix() == 'object' ? call_number.suffix().id() : call_number.suffix();
+ var callnumber_composite_key = acnc_id + ':' + acnp_id + ':' + call_number.label() + ':' + acns_id;
+ g.copy_shortcut[ call_number.owning_lib() ][ callnumber_composite_key ] = call_number.id();
+ if (! g.org_label_existing_copy_map[ call_number.owning_lib() ][ callnumber_composite_key ]) {
+ g.org_label_existing_copy_map[ call_number.owning_lib() ][ callnumber_composite_key ] = [];
}
- g.org_label_existing_copy_map[ call_number.owning_lib() ][ call_number.label() ].push( copy );
+ g.org_label_existing_copy_map[ call_number.owning_lib() ][ callnumber_composite_key ].push( copy );
}
/***********************************************************************************************************/
get_contentWindow(summary).xulG = { 'docid' : g.doc_id };
/***********************************************************************************************************/
- /* For the call number drop down */
+ /* Setup pcrud and fetch the monographic parts for this bib */
- if (g.existing_copies.length > 0 || !g.copy_shortcut) {
- g.list_callnumbers(g.doc_id, label_class);
- }
+ dojo.require('openils.PermaCrud');
+ g.pcrud = new openils.PermaCrud({'authtoken':ses()});
+ g.parts = g.pcrud.search('bmp',{'record':g.doc_id},{'order_by': { 'bmp' : 'label_sortkey' } });
+ g.parts_hash = util.functional.convert_object_list_to_hash( g.parts );
+
+ /***********************************************************************************************************/
+ /* For the batch drop downs */
+
+ g.list_classes();
+ g.list_callnumbers(g.doc_id, g.label_class);
+ g.render_batch_button();
/***********************************************************************************************************/
/* render the orgs and volumes/input */
var rows = document.getElementById('rows');
- var node_id = 0;
+ g.ou_ids = [];
for (var i = 0; i < ou_ids.length; i++) {
try {
var org = g.data.hash.aou[ ou_ids[i] ];
var row = document.createElement('row'); rows.appendChild(row); row.setAttribute('ou_id',ou_ids[i]);
g.render_library_label(row,ou_ids[i]);
g.render_volume_count_entry( row, ou_ids[i] );
+ g.ou_ids.push( ou_ids[i] );
}
} catch(E) {
g.error.sdump('D_ERROR',E);
}
}
+ g.common_ancestor_ou_ids = util.fm_utils.find_common_aou_ancestors( g.ou_ids ).reverse();
+
+ /***********************************************************************************************************/
+ /* For the remainder batch drop downs */
+
+ g.list_prefixes();
+ g.list_suffixes();
+
+ /************/
g.load_prefs();
+ if (g.existing_copies.length > 0) {
+ g.gather_copies_soon();
+ }
+
+ try {
+ $('main').parentNode.scrollLeft = 9999;
+ } catch(E) {
+ dump('Error in volume_copy_creator.js, my_init(), trying to auto-scroll to the far right: ' + E + '\n');
+ }
+
} catch(E) {
var err_msg = $("commonStrings").getFormattedString('common.exception', ['cat/volume_copy_creator.js', E]);
try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); dump(js2JSON(E)); }
g.render_volume_count_entry = function(row,ou_id) {
var hb = document.createElement('vbox'); row.appendChild(hb);
var tb = document.createElement('textbox'); hb.appendChild(tb);
+ if (g.use_defaults) {
+ tb.value = 1; // default to 1 volume per org
+ tb.select();
+ }
tb.setAttribute('ou_id',ou_id); tb.setAttribute('size','3'); tb.setAttribute('cols','3');
- tb.setAttribute('rel_vert_pos','1');
+ tb.setAttribute('rel_vert_pos',rel_vert_pos_volume_count);
if ( (!g.copy_shortcut) && (!g.last_focus) ) { tb.focus(); g.last_focus = tb; }
var node;
function render_copy_count_entry(ev) {
return;
}
if (node) { row.removeChild(node); node = null; }
- //ev.target.disabled = true;
node = g.render_callnumber_copy_count_entry(row,ou_id,ev.target.value);
}
}
- util.widgets.apply_vertical_tab_on_enter_handler(
- tb,
- function() { render_copy_count_entry({'target':tb}); setTimeout(function(){util.widgets.vertical_tab(tb);},0); }
+ util.widgets.apply_vertical_tab_on_enter_handler(
+ tb,
+ function() { render_copy_count_entry({'target':tb}); setTimeout(function(){util.widgets.vertical_tab(tb);},0); },
+ g.delay_gather_copies_soon
);
tb.addEventListener( 'change', render_copy_count_entry, false);
+ tb.addEventListener( 'change', g.gather_copies_soon, false);
tb.addEventListener( 'focus', function(ev) { g.last_focus = ev.target; }, false );
setTimeout(
function() {
).length;
render_copy_count_entry({'target':tb});
tb.disabled = true;
+ } else if (tb.value) {
+ // since we're now supplying a default
+ render_copy_count_entry({'target':tb});
+ setTimeout(
+ function() {
+ util.widgets.vertical_tab(tb);
+ }, 0
+ );
}
} catch(E) {
alert(E);
var rows = grid.lastChild;
var r = document.createElement('row'); rows.appendChild( r );
var x = document.createElement('label'); r.appendChild(x);
- x.setAttribute('value', $("catStrings").getString('staff.cat.volume_copy_creator.render_callnumber_copy_count_entry.call_nums')); x.setAttribute('style','font-weight: bold');
+ x.setAttribute('value', $("catStrings").getString('staff.cat.volume_copy_creator.render_callnumber_copy_count_entry.classification'));
+ x.setAttribute('style','font-weight: bold');
x = document.createElement('label'); r.appendChild(x);
- x.setAttribute('value',$("catStrings").getString('staff.cat.volume_copy_creator.render_callnumber_copy_count_entry.num_of_copies')); x.setAttribute('style','font-weight: bold');
- x.setAttribute('size','3'); x.setAttribute('cols','3');
-
- function handle_change(call_number_column_textbox,number_of_copies_column_textbox,barcode_column_box) {
- if (call_number_column_textbox.value == '') return;
- if (isNaN( Number( number_of_copies_column_textbox.value ) )) return;
+ x.setAttribute('value', $("catStrings").getString('staff.cat.volume_copy_creator.render_callnumber_copy_count_entry.prefix'));
+ x.setAttribute('style','font-weight: bold');
+ x = document.createElement('label'); r.appendChild(x);
+ x.setAttribute('value', $("catStrings").getString('staff.cat.volume_copy_creator.render_callnumber_copy_count_entry.call_nums'));
+ x.setAttribute('style','font-weight: bold');
+ x = document.createElement('label'); r.appendChild(x);
+ x.setAttribute('value', $("catStrings").getString('staff.cat.volume_copy_creator.render_callnumber_copy_count_entry.suffix'));
+ x.setAttribute('style','font-weight: bold');
+ x = document.createElement('label'); r.appendChild(x);
+ x.setAttribute('value',$("catStrings").getString('staff.cat.volume_copy_creator.render_callnumber_copy_count_entry.num_of_copies'));
+ x.setAttribute('style','font-weight: bold');
+ x = document.createElement('label'); r.appendChild(x);
+ x.setAttribute('value',$("catStrings").getString('staff.cat.volume_copy_creator.render_callnumber_copy_count_entry.barcodes_and_parts'));
+ x.setAttribute('style','font-weight: bold');
+
+ function handle_change_precipitating_barcode_rendering(
+ callnumber_composite_key,
+ number_of_copies_column_textbox,
+ barcode_column_box
+ ) {
+ dump('handle_change_precipitating_barcode_rendering\n');
+
+ if (isNaN( Number( number_of_copies_column_textbox.value ) )) {
+ dump('1:handle_change_precipitating_barcode_rendering early return\n');
+ return;
+ }
if ( Number( number_of_copies_column_textbox.value ) > g_max_copies_that_can_be_added_at_a_time_per_volume ) {
g.error.yns_alert($("catStrings").getFormattedString('staff.cat.volume_copy_creator.render_volume_count_entry.message', [g_max_copies_that_can_be_added_at_a_time_per_volume]),
$("catStrings").getString('staff.cat.volume_copy_creator.render_volume_count_entry.title'),
}
g.render_barcode_entry(
barcode_column_box,
- call_number_column_textbox.value,
+ callnumber_composite_key,
Number(number_of_copies_column_textbox.value),
ou_id
);
- document.getElementById("EditThenCreate").disabled = false;
- document.getElementById("CreateWithDefaults").disabled = false;
+ if (! xulG.unified_interface) {
+ document.getElementById("EditThenCreate").disabled = false;
+ document.getElementById("CreateWithDefaults").disabled = false;
+ } else {
+ document.getElementById("Create").disabled = false;
+ }
}
- function handle_change_call_number_column_textbox(ev) {
- var _call_number_column_textbox = ev.target;
+ function handle_change_to_callnumber_data(ev) {
+ dump('handle_change_to_callnumber_data\n');
+ var _call_number_column_textbox = ev.target;
var _call_number_column_box = _call_number_column_textbox.parentNode;
- var _number_of_copies_column_box = _call_number_column_box.nextSibling;
+
+ var _classification_column_box = _call_number_column_box.previousSibling.previousSibling; /* two over to the left */
+ var _classification_column_menulist = _classification_column_box.firstChild;
+
+ var _prefix_column_box = _call_number_column_box.previousSibling; /* one over to the left */
+ var _prefix_column_menulist = _prefix_column_box.firstChild;
+
+ var _suffix_column_box = _call_number_column_box.nextSibling; /* one over to the right */
+ var _suffix_column_menulist = _suffix_column_box.firstChild;
+
+ var _number_of_copies_column_box = _call_number_column_box.nextSibling.nextSibling; /* two over to the right */
var _number_of_copies_column_textbox = _number_of_copies_column_box.firstChild;
+
var _barcode_column_box = _number_of_copies_column_box.nextSibling;
- handle_change(_call_number_column_textbox,_number_of_copies_column_textbox,_barcode_column_box);
+
+ var acn_label = _call_number_column_textbox.value;
+ var acnc_id = _classification_column_menulist.value;
+ var acnp_id = _prefix_column_menulist.value;
+ var acns_id = _suffix_column_menulist.value;
+ var callnumber_composite_key = acnc_id + ':' + acnp_id + ':' + acn_label + ':' + acns_id;
+ dump('\tcomposite_key = ' + callnumber_composite_key + '\n');
+
+ _call_number_column_textbox.setAttribute('callkey',callnumber_composite_key);
+ _call_number_column_textbox.setAttribute('acnc_id',acnc_id);
+ _call_number_column_textbox.setAttribute('acnp_id',acnp_id);
+ _call_number_column_textbox.setAttribute('acns_id',acns_id);
+
+ handle_change_precipitating_barcode_rendering(
+ callnumber_composite_key,
+ _number_of_copies_column_textbox,
+ _barcode_column_box
+ );
}
function handle_change_number_of_copies_column_textbox(ev) {
- var _number_of_copies_column_textbox = ev.target;
+ dump('handle_change_number_of_copies_column_textbox\n');
+ var _number_of_copies_column_textbox = ev.target;
var _number_of_copies_column_box = _number_of_copies_column_textbox.parentNode;
- var _call_number_column_box = _number_of_copies_column_box.previousSibling;
+ var _call_number_column_box = _number_of_copies_column_box.previousSibling.previousSibling; /* two over */
var _call_number_column_textbox = _call_number_column_box.firstChild;
- var _barcode_column_box = _number_of_copies_column_box.nextSibling;
- handle_change(_call_number_column_textbox,_number_of_copies_column_textbox,_barcode_column_box);
+ handle_change_to_callnumber_data({'target':_call_number_column_textbox}); // let this guy do the work
}
for (var i = 0; i < count; i++) {
var r = document.createElement('row'); rows.appendChild(r);
- var call_number_column_box = document.createElement('vbox'); r.appendChild(call_number_column_box);
- var number_of_copies_column_box = document.createElement('vbox'); r.appendChild(number_of_copies_column_box);
- var barcode_column_box = document.createElement('vbox'); r.appendChild(barcode_column_box);
- var call_number_column_textbox = document.createElement('textbox'); call_number_column_box.appendChild(call_number_column_textbox);
- call_number_column_textbox.setAttribute('rel_vert_pos','2');
- call_number_column_textbox.setAttribute('ou_id',ou_id);
- util.widgets.apply_vertical_tab_on_enter_handler(
- call_number_column_textbox,
- function() { handle_change_call_number_column_textbox({'target':call_number_column_textbox}); setTimeout(function(){util.widgets.vertical_tab(call_number_column_textbox);},0); }
- );
- var number_of_copies_column_textbox = document.createElement('textbox'); number_of_copies_column_box.appendChild(number_of_copies_column_textbox);
- number_of_copies_column_textbox.setAttribute('size','3'); number_of_copies_column_textbox.setAttribute('cols','3');
- number_of_copies_column_textbox.setAttribute('rel_vert_pos','3');
- number_of_copies_column_textbox.setAttribute('ou_id',ou_id);
- util.widgets.apply_vertical_tab_on_enter_handler(
- number_of_copies_column_textbox,
- function() { handle_change_number_of_copies_column_textbox({'target':number_of_copies_column_textbox}); setTimeout(function(){util.widgets.vertical_tab(number_of_copies_column_textbox);},0); }
- );
- call_number_column_textbox.addEventListener( 'change', handle_change_call_number_column_textbox, false);
- call_number_column_textbox.addEventListener( 'focus', function(ev) { g.last_focus = ev.target; }, false );
- number_of_copies_column_textbox.addEventListener( 'change', handle_change_number_of_copies_column_textbox, false);
- number_of_copies_column_textbox.addEventListener( 'focus', function(ev) { g.last_focus = ev.target; }, false );
- if ( !g.last_focus ) { number_of_copies_column_textbox.focus(); g.last_focus = number_of_copies_column_textbox; }
+ /**** CLASSIFICATION COLUMN ****/
+ var classification_column_box = document.createElement('vbox');
+ r.appendChild(classification_column_box);
+
+ /**** PREFIX COLUMN ****/
+ var prefix_column_box = document.createElement('vbox');
+ r.appendChild(prefix_column_box);
+
+ /**** CALLNUMBER COLUMN ****/
+ var call_number_column_box = document.createElement('vbox');
+ r.appendChild(call_number_column_box);
+ var call_number_column_textbox = document.createElement('textbox');
+ call_number_column_box.appendChild(call_number_column_textbox);
+ if (g.use_defaults && $('marc_cn').firstChild) {
+ // default to first real value from batch callnumber menu
+ var menupopup = $('marc_cn').firstChild.firstChild;
+ if (menupopup.childNodes.length > 1) {
+ call_number_column_textbox.value = menupopup.childNodes[1].getAttribute('label');
+ call_number_column_textbox.select();
+ }
+ }
+ call_number_column_textbox.setAttribute('rel_vert_pos',rel_vert_pos_call_number);
+ call_number_column_textbox.setAttribute('ou_id',ou_id);
+ util.widgets.apply_vertical_tab_on_enter_handler(
+ call_number_column_textbox,
+ function() {
+ handle_change_to_callnumber_data({'target':call_number_column_textbox});
+ setTimeout(
+ function(){
+ util.widgets.vertical_tab(call_number_column_textbox);
+ },0
+ );
+ },
+ g.delay_gather_copies_soon
+ );
+ call_number_column_textbox.addEventListener( 'change', handle_change_to_callnumber_data, false);
+ call_number_column_textbox.addEventListener( 'change', g.gather_copies_soon, false);
+ call_number_column_textbox.addEventListener( 'focus', function(ev) { g.last_focus = ev.target; }, false );
+
+ /**** CLASSIFICATION COLUMN revisited ****/
+ var classification_column_menulist = g.render_class_menu(call_number_column_textbox);
+ classification_column_menulist.addEventListener(
+ 'command',
+ function() {
+ handle_change_to_callnumber_data({'target':call_number_column_textbox});
+ }
+ ,false
+ );
+ classification_column_box.appendChild(classification_column_menulist);
+
+ /**** PREFIX COLUMN revisited ****/
+ var prefix_column_menulist = g.render_prefix_menu(call_number_column_textbox);
+ prefix_column_menulist.addEventListener(
+ 'command',
+ function() {
+ handle_change_to_callnumber_data({'target':call_number_column_textbox});
+ }
+ ,false
+ );
+
+ prefix_column_box.appendChild(prefix_column_menulist);
+
+ /**** SUFFIX COLUMN ****/
+ var suffix_column_box = document.createElement('vbox');
+ r.appendChild(suffix_column_box);
+ var suffix_column_menulist = g.render_suffix_menu(call_number_column_textbox);
+ suffix_column_menulist.addEventListener(
+ 'command',
+ function() {
+ handle_change_to_callnumber_data({'target':call_number_column_textbox});
+ }
+ ,false
+ );
+ suffix_column_box.appendChild(suffix_column_menulist);
+
+ /**** NUMBER OF COPIES COLUMN ****/
+ var number_of_copies_column_box = document.createElement('vbox');
+ r.appendChild(number_of_copies_column_box);
+ var number_of_copies_column_textbox = document.createElement('textbox');
+ number_of_copies_column_box.appendChild(number_of_copies_column_textbox);
+ if (g.use_defaults) {
+ // default to one copy per call number
+ number_of_copies_column_textbox.value = 1;
+ number_of_copies_column_textbox.select();
+ }
+ number_of_copies_column_textbox.setAttribute('size','3'); number_of_copies_column_textbox.setAttribute('cols','3');
+ number_of_copies_column_textbox.setAttribute('rel_vert_pos',rel_vert_pos_copy_count);
+ number_of_copies_column_textbox.setAttribute('ou_id',ou_id);
+ util.widgets.apply_vertical_tab_on_enter_handler(
+ number_of_copies_column_textbox,
+ function() {
+ handle_change_number_of_copies_column_textbox({'target':number_of_copies_column_textbox});
+ setTimeout(
+ function(){
+ util.widgets.vertical_tab(number_of_copies_column_textbox);
+ },0
+ );
+ },
+ g.delay_gather_copies_soon
+ );
+ number_of_copies_column_textbox.addEventListener( 'change', handle_change_number_of_copies_column_textbox, false);
+ number_of_copies_column_textbox.addEventListener( 'change', g.gather_copies_soon, false);
+ number_of_copies_column_textbox.addEventListener( 'focus', function(ev) { g.last_focus = ev.target; }, false );
+ if ( !g.last_focus ) { number_of_copies_column_textbox.focus(); g.last_focus = number_of_copies_column_textbox; }
+
+ /**** BARCODE COLUMN ****/
+ var barcode_column_box = document.createElement('vbox');
+ r.appendChild(barcode_column_box);
setTimeout(
function(idx,call_number_column_textbox,number_of_copies_column_textbox){
try {
JSAN.use('util.functional');
if (g.copy_shortcut) {
- var label = util.functional.map_object_to_list(
+ var callnumber_composite_key = util.functional.map_object_to_list(
g.copy_shortcut[ou_id],
function(o,i) {
return i;
}
)[idx];
if (g.org_label_existing_copy_map[ou_id]) {
- var num_of_copies = g.org_label_existing_copy_map[ou_id][label].length;
+ var num_of_copies = g.org_label_existing_copy_map[ou_id][callnumber_composite_key].length;
if (num_of_copies>0) {
number_of_copies_column_textbox.value = num_of_copies;
number_of_copies_column_textbox.disabled = true;
}
}
- call_number_column_textbox.value = label;
- handle_change_call_number_column_textbox({'target':call_number_column_textbox});
- if (g.existing_copies.length < 1) {
- call_number_column_textbox.disabled = true;
+ var acn_label = callnumber_composite_key.split(/:/).slice(2,-1).join(':');
+ var acnc_id = callnumber_composite_key.split(/:/)[0];
+ var acnp_id = callnumber_composite_key.split(/:/)[1];
+ var acns_id = callnumber_composite_key.split(/:/).slice(-1)[0];
+ call_number_column_textbox.value = acn_label;
+ classification_column_menulist.value = acnc_id;
+ prefix_column_menulist.value = acnp_id;
+ suffix_column_menulist.value = acns_id;
+ handle_change_to_callnumber_data({'target':call_number_column_textbox});
+ } else {
+
+ // if we're providing defaults, keep on rendering
+ if (call_number_column_textbox.value) {
+ util.widgets.dispatch('change',call_number_column_textbox);
+ }
+ if (number_of_copies_column_textbox.value) {
+ util.widgets.dispatch('change',number_of_copies_column_textbox);
}
}
} catch(E) {
return grid;
}
-g.render_barcode_entry = function(node,callnumber,count,ou_id) {
+g.render_part_menu = function(barcode_tb) {
+ var hbox = document.createElement('hbox');
+ var menulist = document.createElement('menulist');
+ menulist.setAttribute('editable','true');
+ hbox.appendChild(menulist);
+ var button = document.createElement('button');
+ button.setAttribute('label',$('catStrings').getString('staff.cat.volume_copy_creator.create_part.btn.label'));
+ button.hidden = true;
+ hbox.appendChild(button);
+
+ var menupopup = document.createElement('menupopup');
+ menulist.appendChild(menupopup);
+ g.render_part_menuitems(menupopup);
+
+ button.addEventListener(
+ 'command',
+ function(ev) {
+ var new_part = new bmp();
+ new_part.isnew(1);
+ new_part.label(menulist.value);
+ new_part.record(g.doc_id);
+ g.pcrud.create(new_part, {
+ "oncomplete": function (r, objs) {
+ var db_part = objs[0];
+ if (!db_part) { return; }
+ g.parts.push( db_part );
+ g.parts_hash[ db_part.id() ] = db_part;
+ g.render_part_menuitems(menupopup);
+ if (menulist.selectedItem) {
+ barcode_tb.setAttribute('bmp_id',menulist.selectedItem.value);
+ button.hidden = true;
+ }
+ g.gather_copies_soon();
+ }
+ });
+ },
+ false
+ );
+
+ menulist.addEventListener(
+ 'change',
+ function(ev) {
+ if (! ev.target.selectedItem) {
+ button.hidden = false;
+ }
+ },
+ false
+ );
+ menulist.addEventListener('change',g.gather_copies_soon,false);
+ menulist.addEventListener(
+ 'command',
+ function(ev) {
+ barcode_tb.setAttribute('bmp_id',menulist.selectedItem.value);
+ button.hidden = true;
+ },
+ false
+ );
+ menulist.addEventListener('command',g.gather_copies_soon,false);
+
+ return hbox;
+}
+
+g.render_part_menuitems = function(menupopup) {
+ util.widgets.remove_children(menupopup);
+ var menuitem = document.createElement('menuitem');
+ menuitem.setAttribute('label','');
+ menuitem.setAttribute('value','');
+ menupopup.appendChild(menuitem);
+ for (var i = 0; i < g.parts.length; i++) {
+ var menuitem = document.createElement('menuitem');
+ menuitem.setAttribute('label',g.parts[i].label());
+ menuitem.setAttribute('value',g.parts[i].id());
+ menupopup.appendChild(menuitem);
+ }
+
+}
+
+g.render_barcode_entry = function(node,callnumber_composite_key,count,ou_id) {
try {
+ dump('g.render_barcode_entry(node,'+callnumber_composite_key+','+count+','+ou_id+'\n');
function ready_to_create(ev) {
- document.getElementById("EditThenCreate").disabled = false;
- document.getElementById("CreateWithDefaults").disabled = false;
+ if (! xulG.unified_interface) {
+ document.getElementById("EditThenCreate").disabled = false;
+ document.getElementById("CreateWithDefaults").disabled = false;
+ } else {
+ document.getElementById("Create").disabled = false;
+ }
}
- JSAN.use('util.barcode');
+ JSAN.use('util.barcode');
for (var i = 0; i < count; i++) {
- var tb; var set_handlers = false;
+ var tb_part_box;
+ var tb;
+ var part_menu;
+ var set_handlers = false;
if (typeof node.childNodes[i] == 'undefined') {
- tb = document.createElement('textbox'); node.appendChild(tb);
+ tb_part_box = document.createElement('hbox');
+ node.appendChild(tb_part_box);
+ tb = document.createElement('textbox');
+ tb_part_box.appendChild(tb);
+ part_menu = g.render_part_menu(tb);
+ tb_part_box.appendChild(part_menu);
set_handlers = true;
} else {
- tb = node.childNodes[i];
+ tb_part_box = node.childNodes[i];
+ tb = tb_part_box.firstChild;
+ part_menu = tb_part_box.lastChild;
}
tb.setAttribute('ou_id',ou_id);
- tb.setAttribute('callnumber',callnumber);
- tb.setAttribute('rel_vert_pos','4');
+ tb.setAttribute('callkey',callnumber_composite_key);
+ tb.setAttribute('rel_vert_pos',rel_vert_pos_barcode);
+ part_menu.firstChild.setAttribute('rel_vert_pos',rel_vert_pos_part);
if (!tb.value && g.org_label_existing_copy_map[ ou_id ]) {
- tb.value = g.org_label_existing_copy_map[ ou_id ][ callnumber ][i].barcode();
- tb.setAttribute('acp_id', g.org_label_existing_copy_map[ ou_id ][ callnumber ][i].id());
+ tb.value = g.org_label_existing_copy_map[ ou_id ][ callnumber_composite_key ][i].barcode();
+ tb.setAttribute('acp_id', g.org_label_existing_copy_map[ ou_id ][ callnumber_composite_key ][i].id());
+ var temp_parts = g.org_label_existing_copy_map[ ou_id ][ callnumber_composite_key ][i].parts();
+ temp_parts = util.functional.filter_list(
+ temp_parts,
+ function(p) {
+ return p.record() == g.doc_id; // filter out foreign parts
+ }
+ );
+ if (temp_parts.length > 0) {
+ tb.setAttribute('bmp_id',temp_parts[0].id());
+ part_menu.firstChild.value = g.parts_hash[ temp_parts[0].id() ].label();
+ }
tb.select();
if (! g.first_focus) { g.first_focus = tb; }
}
+ if (g.use_defaults && ! g.first_focus) {
+ g.first_focus = tb;
+ tb.focus();
+ }
if (set_handlers) {
- util.widgets.apply_vertical_tab_on_enter_handler(
- tb,
- function() { ready_to_create({'target':tb}); setTimeout(function(){util.widgets.vertical_tab(tb);},0); }
+ util.widgets.apply_vertical_tab_on_enter_handler(
+ tb,
+ function() { ready_to_create({'target':tb}); setTimeout(function(){util.widgets.vertical_tab(tb);},0); },
+ g.delay_gather_copies_soon
+ );
+ util.widgets.apply_vertical_tab_on_enter_handler(
+ part_menu.firstChild,
+ function() { setTimeout(function(){util.widgets.vertical_tab(part_menu.firstChild);},0); },
+ g.delay_gather_copies_soon
);
tb.addEventListener('change', function(ev) {
var barcode = String( ev.target.value ).replace(/\s/g,'');
setTimeout( function() { ev.target.select(); ev.target.focus(); }, 0);
}
}, false);
+ tb.addEventListener('change', g.gather_copies_soon, false);
tb.addEventListener( 'focus', function(ev) { g.last_focus = ev.target; }, false );
}
}
-
- setTimeout( function() { if (g.first_focus) { g.first_focus.focus(); } }, 0 );
+
+ g.gather_copies_soon();
+ setTimeout( function() { if (g.first_focus) { g.first_focus.focus(); } }, 0 );
} catch(E) {
g.error.sdump('D_ERROR','g.render_barcode_entry: ' + E);
g.generate_barcodes = function() {
try {
- var nodes = document.getElementsByAttribute('rel_vert_pos','4');
+ var nodes = document.getElementsByAttribute('rel_vert_pos',rel_vert_pos_barcode);
if (nodes.length < 1) { return; }
var first_barcode = nodes[0].value;
for (var i = 0; i < barcodes.length; i++) {
nodes[i+1].value = barcodes[i];
nodes[i+1].select();
+ util.widgets.dispatch('change',nodes[i+1]);
}
+ setTimeout(
+ function() {
+ g.gather_copies_soon();
+ },0
+ );
+
} catch(E) {
g.error.sdump('D_ERROR','g.generate_barcodes: ' + E);
}
}
-g.new_node_id = -1;
-
-g.stash_and_close = function(param) {
+g.delay_gather_copies_soon = function() {
+ if (xulG.unified_interface) {
+ dump('g.delay_gather_copies_soon()\n');
+ g.gather_copies_soon();
+ }
+}
+g.gather_copies_soon = function() {
try {
+ if (!xulG.unified_interface) { return; }
+ dump('g.gather_copies_soon()\n');
+ document.getElementById("Create").disabled = true;
+ if (g.update_copy_editor_timeoutID) {
+ clearTimeout(g.update_copy_editor_timeoutID);
+ }
+ // This function is expensive when it comes to keeping the UI responsive, so let's give it a delay
+ // that quick entry of consecutive fields can override
+ g.update_copy_editor_timeoutID = setTimeout(
+ function() {
+ try {
+ g.gather_copies();
+ xulG.refresh_copy_editor();
+ document.getElementById("Create").disabled = false;
+ } catch(E) {
+ alert('Error in volume_copy_editor.js with g.gather_copies_soon setTimeout func(): ' + E);
+ }
+ }, update_timer
+ );
+ } catch(E) {
+ alert('Error in volume_copy_creator.js, g.gather_copies_soon(): ' + E);
+ }
+}
+g.new_acp_id = -1;
+g.new_acn_id = -1;
+
+g.gather_copies = function() {
+ dump('g.gather_copies()\n');
+ try {
var nl = document.getElementsByTagName('textbox');
- var volumes_hash = {};
+ g.volumes_scaffold = {};
+ /*
+ g.volumes_scaffold = {
+ '#ou_id' : {
+ '#class_id:#prefix_id:#callnumber label:#suffix_id' : {
+ 'callnumber_data' : {
+ 'acn_id' : '#callnumber id',
+ 'acn_label' : '#callnumber label',
+ 'acnc_id' : '#classification_id',
+ 'acnp_id' : '#prefix_id',
+ 'acns_id' : '#suffix_id'
+ },
+ 'barcode_data' :
+ [
+ {
+ 'barcode' : '#barcode',
+ 'acp_id' : '#copy_id',
+ 'bmp_id' : '#part_id'
+ }, ...
+ ]
+ }
+ }, ...
+ }
+ */
var barcodes = [];
-
+ var v_count = 0;
for (var i = 0; i < nl.length; i++) {
- if ( nl[i].getAttribute('rel_vert_pos') == 4 ) barcodes.push( nl[i] );
- if ( nl[i].getAttribute('rel_vert_pos') == 2 ) {
+ if ( nl[i].getAttribute('rel_vert_pos') == rel_vert_pos_barcode ) barcodes.push( nl[i] );
+ if ( nl[i].getAttribute('rel_vert_pos') == rel_vert_pos_call_number ) {
+ v_count++;
var ou_id = nl[i].getAttribute('ou_id');
+ var acn_id = nl[i].getAttribute('acn_id');
+ if (!acn_id) {
+ acn_id = g.new_acn_id--;
+ nl[i].setAttribute('acn_id',acn_id);
+ }
+ var acnc_id = nl[i].getAttribute('acnc_id') || g.label_class;
+ var acnp_id = nl[i].getAttribute('acnp_id') || -1;
+ var acns_id = nl[i].getAttribute('acns_id') || -1;
var callnumber = nl[i].value;
- if (typeof volumes_hash[ou_id] == 'undefined') { volumes_hash[ou_id] = {} }
- if (typeof volumes_hash[ou_id][callnumber] == 'undefined') { volumes_hash[ou_id][callnumber] = [] }
+ if (typeof g.volumes_scaffold[ou_id] == 'undefined') {
+ g.volumes_scaffold[ou_id] = {}
+ }
+ var composite_key = acnc_id + ':' + acnp_id + ':' + callnumber + ':' + acns_id;
+ if (typeof g.volumes_scaffold[ou_id][composite_key] == 'undefined') {
+ g.volumes_scaffold[ou_id][composite_key] = {
+ //'node' : nl[i],
+ 'callnumber_data' : {
+ 'acn_id' : acn_id,
+ 'acn_label' : callnumber,
+ 'acnc_id' : acnc_id,
+ 'acnp_id' : acnp_id,
+ 'acns_id' : acns_id
+ },
+ 'barcode_data' : []
+ }
+ dump('fleshing volumes scaffold with ou_id = ' + ou_id + ' composite_key = ' + composite_key + ' acn_id = ' + acn_id + '\n');
+ }
}
};
-
+ dump('volume_copy_creator: processed ' + nl.length + ' textbox nodes, consisting of ' + barcodes.length + ' barcodes and ' + v_count + 'volumes\n');
+ dump('volume scaffold = ' + js2JSON(g.volumes_scaffold) + '\n');
+
for (var i = 0; i < barcodes.length; i++) {
- var acp_id = barcodes[i].getAttribute('acp_id') || g.new_node_id--;
+ var acp_id = barcodes[i].getAttribute('acp_id') || g.new_acp_id--;
var ou_id = barcodes[i].getAttribute('ou_id');
- var callnumber = barcodes[i].getAttribute('callnumber');
+ var callnumber_composite_key = barcodes[i].getAttribute('callkey');
var barcode = barcodes[i].value;
+ var bmp_id = barcodes[i].getAttribute('bmp_id');
- if (typeof volumes_hash[ou_id] == 'undefined') { volumes_hash[ou_id] = {} }
- if (typeof volumes_hash[ou_id][callnumber] == 'undefined') { volumes_hash[ou_id][callnumber] = [] }
+ dump('placing ' + barcode + ' for ou = ' + ou_id + ' into composite_key bin ' + callnumber_composite_key + '\n');
- if (barcode != '') volumes_hash[ou_id][callnumber].push( { 'barcode' : barcode, 'acp_id' : acp_id } );
+ if (typeof g.volumes_scaffold[ou_id] == 'undefined') {
+ dump('1: I want to remove this soon, so alert me if it is getting used, ou_id = ' + ou_id + '\n');
+ g.volumes_scaffold[ou_id] = {}
+ }
+ if (typeof g.volumes_scaffold[ou_id][callnumber_composite_key] == 'undefined') {
+ dump('2: when does this happen, and why? ou_id = ' + ou_id + ' callnumber_composite_key = ' + callnumber_composite_key + '\n');
+ // one way this can happen, race condition between this function and editing a widget
+ g.volumes_scaffold[ou_id][callnumber_composite_key] = {
+ 'callnumber_data' : {
+ // not ideal, but hey...
+ 'acn_label' : callnumber_composite_key.split(/:/).slice(2,-1).join(':'),
+ 'acnc_id' : callnumber_composite_key.split(/:/)[0],
+ 'acnp_id' : callnumber_composite_key.split(/:/)[1],
+ 'acns_id' : callnumber_composite_key.split(/:/).slice(-1)[0]
+ },
+ 'barcode_data' : []
+ }
+ }
+
+ if (barcode != '') {
+ g.volumes_scaffold[ou_id][callnumber_composite_key].barcode_data.push(
+ {
+ 'barcode' : barcode,
+ 'acp_id' : acp_id,
+ 'bmp_id' : bmp_id
+ }
+ );
+ }
}
var volumes = [];
var copies = [];
- var volume_labels = {};
+ var volume_data = {};
function new_copy(acp_id,ou_id,acn_id,barcode) {
var copy = new acp();
return copy;
}
- for (var ou_id in volumes_hash) {
- for (var cn_label in volumes_hash[ou_id]) {
+ for (var ou_id in g.volumes_scaffold) {
+ for (var composite_key in g.volumes_scaffold[ou_id]) {
+ for (var i = 0; i < g.volumes_scaffold[ou_id][composite_key].barcode_data.length; i++) {
+ var barcode = g.volumes_scaffold[ou_id][composite_key].barcode_data[i].barcode;
+ var acp_id = g.volumes_scaffold[ou_id][composite_key].barcode_data[i].acp_id;
+ var bmp_id = g.volumes_scaffold[ou_id][composite_key].barcode_data[i].bmp_id;
+ var acn_id = g.volumes_scaffold[ou_id][composite_key].callnumber_data.acn_id;
+ dump('gather_copies(): barcode = ' + barcode + ' acp_id = ' + acp_id + ' bmp_id = ' + bmp_id + ' acn_id = ' + acn_id + ' composite_key = ' + composite_key + '\n');
+ var copy = g.id_copy_map[ acp_id ];
+ if (!copy) {
+ copy = new_copy(acp_id,ou_id,acn_id,barcode);
+ g.id_copy_map[ acp_id ] = copy;
+ } else {
+ copy.ischanged( get_db_true() );
+ }
+ copy.barcode( barcode );
+ copy.call_number( acn_id );
+ var temp_parts = util.functional.filter_list(
+ copy.parts() || [],
+ function(p) {
+ return (p.record() != g.doc_id); // filter out parts for this bib
+ }
+ );
+ if (bmp_id) {
+ temp_parts.push( g.parts_hash[ bmp_id ] );
+ }
+ copy.parts( temp_parts );
+ copies.push( copy );
+ }
+ }
+ }
+
+ xulG.copies = copies;
+ return copies;
- var acn_id = g.network.simple_request(
- 'FM_ACN_FIND_OR_CREATE',
- [ ses(), cn_label, g.doc_id, ou_id ]
- );
+ } catch(E) {
+ alert('Error in volume_copy_creator.js, g.gather_copies():' + E);
+ }
+}
- if (typeof acn_id.ilsevent != 'undefined') {
- g.error.standard_unexpected_error_alert($("catStrings").getFormattedString('staff.cat.volume_copy_creator.stash_and_close.problem_with_volume', [cn]), acn_id);
- continue;
- }
+g.vivicate_update_volumes = function() {
+ try {
+ var volumes = [];
+ for (var ou_id in g.volumes_scaffold) {
+ for (var composite_key in g.volumes_scaffold[ou_id]) {
- volume_labels[ acn_id ] = { 'label' : cn_label, 'owning_lib' : ou_id };
+ var callnumber_data = g.volumes_scaffold[ou_id][composite_key].callnumber_data;
+ var acn_id = callnumber_data.acn_id;
+ var acnp_id = callnumber_data.acnp_id;
+ var acns_id = callnumber_data.acns_id;
+ var acnc_id = callnumber_data.acnc_id;
- for (var i = 0; i < volumes_hash[ou_id][cn_label].length; i++) {
- var barcode = volumes_hash[ou_id][cn_label][i].barcode;
- var acp_id = volumes_hash[ou_id][cn_label][i].acp_id;
- var copy;
- if (acp_id < 0) {
- copy = new_copy(acp_id,ou_id,acn_id,barcode);
- } else {
- copy = g.id_copy_map[ acp_id ];
- copy.barcode( barcode );
- copy.call_number( acn_id );
- copy.ischanged('1');
+ if (acn_id < 0) {
+
+ var acn_blob = g.network.simple_request(
+ 'FM_ACN_FIND_OR_CREATE',
+ [ ses(), callnumber_data.acn_label, g.doc_id, ou_id, acnp_id, acns_id, acnc_id ]
+ );
+ dump('FM_ACN_FIND_OR_CREATE: label = ' + callnumber_data.acn_label
+ + ' doc = ' + g.doc_id + ' ou = ' + ou_id + ' acnp = ' + acnp_id + ' acns = ' + acns_id + ' acnc = ' + acnc_id + '\n');
+
+ if (typeof acn_blob.ilsevent != 'undefined') {
+ alert('Error in g.vivicate_update_volumes, acn_id = ' + acn_id + ' acn_blob = ' + js2JSON(acn_blob));
+ continue;
}
- copies.push( copy );
+
+ acn_id = acn_blob.acn_id;
+
+ if (typeof g.acn_map[ acn_id ] == 'undefined') {
+ var temp_acn = g.network.simple_request(
+ 'FM_ACN_RETRIEVE.authoritative',
+ [ acn_id ]
+ );
+ if (typeof temp_acn.ilsevent != 'undefined') {
+ alert('Error in g.vivicate_update_volumes, acn_id = ' + acn_id + ' temp_acn = ' + js2JSON(temp_acn));
+ continue;
+ }
+ g.acn_map[ acn_id ] = temp_acn;
+ if (callnumber_data.acn_id < 0) {
+ g.acn_map[ callnumber_data.acn_id ] = temp_acn;
+ }
+ }
+
+ }
+/*
+ var my_acn = g.acn_map[ acn_id ];
+
+ var node = g.volumes_scaffold[ou_id][composite_key].node;
+ var class_menulist = node.parentNode.previousSibling.previousSibling.firstChild;
+ var prefix_menulist = node.parentNode.previousSibling.firstChild;
+ var suffix_menulist = node.parentNode.nextSibling.firstChild;
+
+ if ( String(class_menulist.value) != String(my_acn.label_class()) {
+ my_acn.label_class( class_menulist.value );
+ my_acn.ischanged( get_db_true() );
+ }
+ if ( String(prefix_menulist.value) != String(my_acn.prefix()) {
+ my_acn.prefix( prefix_menulist.value );
+ my_acn.ischanged( get_db_true() );
+ }
+ if ( String(suffix_menulist.value) != String(my_acn.suffix()) {
+ my_acn.suffix( suffix_menulist.value );
+ my_acn.ischanged( get_db_true() );
+ }
+
+ if (get_bool( my_acn.ischanged() )) {
+ volumes.push( my_acn );
}
+*/
}
}
+ if (volumes.length > 0) {
+ if (typeof xul_param('update_volume') == 'function') {
+ xul_param('update_volume')(volumes);
+ } else {
+ var r = g.network.simple_request(
+ 'FM_ACN_TREE_UPDATE',
+ [ ses(),volumes, false, { 'auto_merge_vols' : false } ]
+ );
+ if (typeof r.ilsevent != 'undefined') {
+ alert('error with volume update: ' + js2JSON(r));
+ }
+ }
+ }
+ } catch(E) {
+ alert('Error in volume_copy_creator.js, vivicate_volumes(): ' + E);
+ }
+}
+
+g.stash_and_close = function(param) {
+
+ try {
+
+ var copies;
+ if (xulG.unified_interface) {
+ copies = xulG.copies;
+ } else {
+ copies = g.gather_copies();
+ copies = blob.copies;
+ }
var dont_close = false;
- JSAN.use('util.window'); var win = new util.window();
+
+ g.vivicate_update_volumes();
+ for (var i = 0; i < copies.length; i++) {
+ var acn_id = copies[i].call_number();
+ if (typeof g.acn_map[acn_id] != 'undefined') {
+ // handle vivicated-callnumbers
+ copies[i].call_number( g.acn_map[acn_id].id() );
+ } else {
+ alert('error in stash and close, acn_id = ' + acn_id);
+ }
+ }
+
if (copies.length > 0) {
- JSAN.use('cat.util');
if (param == 'edit') {
+ JSAN.use('cat.util');
copies = cat.util.spawn_copy_editor( { 'edit' : true, 'docid' : g.doc_id, 'copies' : copies, 'caller_handles_update' : true });
}
if (typeof xul_param('update_copy') == 'function') {
[ ses(),copies, true ]
);
if (typeof r.ilsevent != 'undefined') {
- g.error.standard_unexpected_error_alert('copy update',r);
+ alert('error with copy update:' + js2JSON(r));
}
}
try {
urls.XUL_SPINE_LABEL,
{ 'tab_name' : $("catStrings").getString('staff.cat.util.spine_editor.tab_name') },
{
- 'barcodes' : util.functional.map_list( copies, function(o){return o.barcode();})
+ 'barcodes' : util.functional.map_list( copies, function(o){return o.barcode();})
}
);
}
} catch(E) {
- g.error.standard_unexpected_error_alert($(catStrings).getString('staff.cat.volume_copy_creator.stash_and_close.tree_err2'),E);
+ alert('2: Error in volume_copy_creator.js with g.stash_and_close(): ' + E);
}
}
try { if (typeof window.refresh == 'function') { window.refresh(); } } catch(E) { dump(E+'\n'); }
try { if (typeof g.refresh == 'function') { g.refresh(); } } catch(E) { dump(E+'\n'); }
+ if (typeof xulG.unlock_copy_editor == 'function') {
+ xulG.unlock_copy_editor();
+ }
+
if (! dont_close) { xulG.close_tab(); }
} catch(E) {
- g.error.standard_unexpected_error_alert($(catStrings).getString('staff.cat.volume_copy_creator.stash_and_close.tree_err3'),E);
+ alert('3: Error in volume_copy_creator.js with g.stash_and_close(): ' + E);
}
}
}
} catch(E) {
- g.error.standard_unexpected_error_alert($(catStrings).getString('staff.cat.volume_copy_creator.load_prefs.err_retrieving_prefs'),E);
-
+ alert('Error in volume_copy_creator.js with g.load_prefs(): ' + E);
}
}
);
file.close();
} catch(E) {
- g.error.standard_unexpected_error_alert($(catStrings).getString('staff.cat.volume_copy_creator.save_prefs.err_storing_prefs'),E);
+ alert('Error in volume_copy_creator.js with g.save_prefs(): ' + E);
+ }
+}
+
+g.render_class_menu = function(call_number_tb) {
+ var ml = util.widgets.make_menulist(
+ util.functional.map_list(
+ g.data.list.acnc,
+ function(o) {
+ return [ o.name(), o.id() ];
+ }
+ )
+ );
+ ml.setAttribute('rel_vert_pos',rel_vert_pos_call_number_classification);
+ ml.addEventListener(
+ 'command',
+ function() {
+ call_number_tb.setAttribute('acnc_id',ml.value);
+ },
+ false
+ );
+ return ml;
+}
+
+g.render_prefix_menu = function(call_number_tb) {
+ var ou_id = call_number_tb.getAttribute('ou_id');
+ var org = g.data.hash.aou[ ou_id ];
+ var menulist = document.createElement('menulist');
+ var menupopup = document.createElement('menupopup');
+ menulist.appendChild(menupopup);
+ var org_list = []; // order from top of consortium to owning lib
+ while(org) {
+ org_list.unshift(org.id());
+ org = org.parent_ou();
+ if (org && typeof org != 'object') {
+ org = g.data.hash.aou[ org ];
+ }
+ }
+ for (var i = 0; i < org_list.length; i++) {
+ g.render_prefix_menu_items(menupopup,org_list[i]);
+ }
+
+ menulist.setAttribute('rel_vert_pos',rel_vert_pos_call_number_prefix);
+ menulist.addEventListener(
+ 'command',
+ function() {
+ call_number_tb.setAttribute('acnp_id',menulist.value);
+ },
+ false
+ );
+ return menulist;
+}
+
+g.render_prefix_menu_items = function(menupopup,ou_id) {
+ if (typeof g.data.list['acnp_for_lib_'+ou_id] == 'undefined') {
+ g.data.list['acnp_for_lib_'+ou_id] = g.network.simple_request(
+ 'FM_ACNP_RETRIEVE_VIA_PCRUD',
+ [ ses(), {"owning_lib":{"=":ou_id}}, {"order_by":{"acnp":"label_sortkey"}} ]
+ );
+ g.data.stash('list');
+ }
+ for (var i = 0; i < g.data.list['acnp_for_lib_'+ou_id].length; i++) {
+ var my_acnp = g.data.list['acnp_for_lib_'+ou_id][i];
+ var menuitem = document.createElement('menuitem');
+ menupopup.appendChild(menuitem);
+ menuitem.setAttribute(
+ 'label',
+ my_acnp.id() == -1 ? '' :
+ $('catStrings').getFormattedString(
+ 'staff.cat.volume_copy_creator.call_number_prefix.menuitem_label',
+ [
+ my_acnp.label(),
+ g.data.hash.aou[ ou_id ].shortname()
+ ]
+ )
+ );
+ menuitem.setAttribute('value',my_acnp.id());
}
}
+g.render_suffix_menu = function(call_number_tb) {
+ var ou_id = call_number_tb.getAttribute('ou_id');
+ var org = g.data.hash.aou[ ou_id ];
+ var menulist = document.createElement('menulist');
+ var menupopup = document.createElement('menupopup');
+ menulist.appendChild(menupopup);
+ var org_list = []; // order from top of consortium to owning lib
+ while(org) {
+ org_list.unshift(org.id());
+ org = org.parent_ou();
+ if (org && typeof org != 'object') {
+ org = g.data.hash.aou[ org ];
+ }
+ }
+ for (var i = 0; i < org_list.length; i++) {
+ g.render_suffix_menu_items(menupopup,org_list[i]);
+ }
+
+ menulist.setAttribute('rel_vert_pos',rel_vert_pos_call_number_suffix);
+ menulist.addEventListener(
+ 'command',
+ function() {
+ call_number_tb.setAttribute('acns_id',menulist.value);
+ },
+ false
+ );
+ return menulist;
+}
+
+g.render_suffix_menu_items = function(menupopup,ou_id) {
+ if (typeof g.data.list['acns_for_lib_'+ou_id] == 'undefined') {
+ g.data.list['acns_for_lib_'+ou_id] = g.network.simple_request(
+ 'FM_ACNS_RETRIEVE_VIA_PCRUD',
+ [ ses(), {"owning_lib":{"=":ou_id}}, {"order_by":{"acns":"label_sortkey"}} ]
+ );
+ g.data.stash('list');
+ }
+ for (var i = 0; i < g.data.list['acns_for_lib_'+ou_id].length; i++) {
+ var my_acns = g.data.list['acns_for_lib_'+ou_id][i];
+ var menuitem = document.createElement('menuitem');
+ menupopup.appendChild(menuitem);
+ menuitem.setAttribute(
+ 'label',
+ my_acns.id() == -1 ? '' :
+ $('catStrings').getFormattedString(
+ 'staff.cat.volume_copy_creator.call_number_suffix.menuitem_label',
+ [
+ my_acns.label(),
+ g.data.hash.aou[ ou_id ].shortname()
+ ]
+ )
+ );
+ menuitem.setAttribute('value',my_acns.id());
+ }
+}
+
+
g.list_callnumbers = function(doc_id, label_class) {
var cn_blob;
try {
}
var hbox = document.getElementById('marc_cn');
var ml = util.widgets.make_menulist(
- util.functional.map_list(
- cn_blob,
- function(o) {
- for (var i in o) {
- return [ o[i], i ];
+ [
+ [ '', '' ]
+ ].concat(
+ util.functional.map_list(
+ cn_blob,
+ function(o) {
+ for (var i in o) {
+ return [ o[i], i ];
+ }
}
- }
+ )
)
); hbox.appendChild(ml);
ml.setAttribute('editable','true');
ml.setAttribute('width', '200');
+ ml.setAttribute('id', 'marc_cn_menulist');
+}
+
+g.list_classes = function() {
+ var hbox = $('batch_class');
+ var ml = util.widgets.make_menulist(
+ [
+ [ '<No Change>', false ]
+ ].concat(
+ util.functional.map_list(
+ g.data.list.acnc,
+ function(o) {
+ return [ o.name(), o.id() ];
+ }
+ )
+ )
+ ); hbox.appendChild(ml);
+ ml.setAttribute('id','batch_class_menulist');
+ ml.addEventListener(
+ 'command',
+ function() {
+ if (!isNaN(Number(ml.value))) {
+ addCSSClass(hbox,'copy_editor_field_changed');
+ if (xulG.unified_interface) {
+ xulG.notify_of_templatable_field_change('batch_class_menulist',ml.value);
+ }
+ } else {
+ removeCSSClass(hbox,'copy_editor_field_changed');
+ }
+ },
+ false
+ );
+}
+
+g.list_prefixes = function() {
+ var hbox = $('batch_prefix');
+ var ml = util.widgets.make_menulist(
+ [
+ [ '<No Change>', false ]
+ ]
+ ); hbox.appendChild(ml);
+ for (var i = 0; i < g.common_ancestor_ou_ids.length; i++) {
+ g.render_prefix_menu_items(ml.firstChild,g.common_ancestor_ou_ids[i]);
+ }
+ ml.setAttribute('id','batch_prefix_menulist');
+ ml.addEventListener(
+ 'command',
+ function() {
+ if (!isNaN(Number(ml.value))) {
+ addCSSClass(hbox,'copy_editor_field_changed');
+ if (xulG.unified_interface) {
+ xulG.notify_of_templatable_field_change('batch_prefix_menulist',ml.value);
+ }
+ } else {
+ removeCSSClass(hbox,'copy_editor_field_changed');
+ }
+ },
+ false
+ );
+}
+
+g.list_suffixes = function() {
+ var hbox = $('batch_suffix');
+ var ml = util.widgets.make_menulist(
+ [
+ [ '<No Change>', false ]
+ ]
+ ); hbox.appendChild(ml);
+ for (var i = 0; i < g.common_ancestor_ou_ids.length; i++) {
+ g.render_suffix_menu_items(ml.firstChild,g.common_ancestor_ou_ids[i]);
+ }
+ ml.setAttribute('id','batch_suffix_menulist');
+ ml.addEventListener(
+ 'command',
+ function() {
+ if (!isNaN(Number(ml.value))) {
+ addCSSClass(hbox,'copy_editor_field_changed');
+ if (xulG.unified_interface) {
+ xulG.notify_of_templatable_field_change('batch_suffix_menulist',ml.value);
+ }
+ } else {
+ removeCSSClass(hbox,'copy_editor_field_changed');
+ }
+ },
+ false
+ );
+}
+
+g.render_batch_button = function() {
+ var hbox = $('batch_button_box');
var btn = document.createElement('button');
+ btn.setAttribute('id','batch_button');
btn.setAttribute('label',$('catStrings').getString('staff.cat.volume_copy_creator.my_init.btn.label'));
btn.setAttribute('accesskey',$('catStrings').getString('staff.cat.volume_copy_creator.my_init.btn.accesskey'));
btn.setAttribute('image','/xul/server/skin/media/images/down_arrow.gif');
function() {
var nl = document.getElementsByTagName('textbox');
for (var i = 0; i < nl.length; i++) {
- if (nl[i].getAttribute('rel_vert_pos')==2
- && !nl[i].disabled)
- {
- nl[i].value = ml.value;
- util.widgets.dispatch('change',nl[i]);
+ /* label */
+ if (nl[i].getAttribute('rel_vert_pos')==rel_vert_pos_call_number && !nl[i].disabled) {
+ var label = $('marc_cn').firstChild.value;
+ if (label != '') {
+ nl[i].value = label;
+ util.widgets.dispatch('change',nl[i]);
+ }
+ }
+ }
+ nl = document.getElementsByTagName('menulist');
+ for (var i = 0; i < nl.length; i++) {
+ /* classification */
+ if (nl[i].getAttribute('rel_vert_pos')==rel_vert_pos_call_number_classification && !nl[i].disabled) {
+ var value = $('batch_class_menulist').value;
+ if (!isNaN( Number(value) )) {
+ nl[i].value = value;
+ util.widgets.dispatch('command',nl[i]);
+ }
+ }
+ /* prefix */
+ if (nl[i].getAttribute('rel_vert_pos')==rel_vert_pos_call_number_prefix && !nl[i].disabled) {
+ var value = $('batch_prefix_menulist').value;
+ if (!isNaN( Number(value) )) {
+ nl[i].value = value;
+ util.widgets.dispatch('command',nl[i]);
+ }
+ }
+ /* suffix */
+ if (nl[i].getAttribute('rel_vert_pos')==rel_vert_pos_call_number_suffix && !nl[i].disabled) {
+ var value = $('batch_suffix_menulist').value;
+ if (!isNaN( Number(value) )) {
+ nl[i].value = value;
+ util.widgets.dispatch('command',nl[i]);
+ }
}
}
+ setTimeout(
+ function() {
+ g.gather_copies_soon();
+ },0
+ );
if (g.last_focus) setTimeout( function() { g.last_focus.focus(); }, 0 );
- },
+ },
false
);
}
<!-- STYLESHEETS -->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="/xul/server/skin/global.css" type="text/css"?>
+<?xml-stylesheet href="/xul/server/skin/cat.css" type="text/css"?>
<!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
<!-- LOCALIZATION -->
<window id="cat_volume_copy_creator_win"
onload="try { my_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
- width="800" height="580" oils_persist="height width sizemode"
title="&staff.cat.volume_copy_creator.title;"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<messagecatalog id="catStrings" src="/xul/server/locale/<!--#echo var='locale'-->/cat.properties" />
<messagecatalog id="circStrings" src="/xul/server/locale/<!--#echo var='locale'-->/circ.properties" />
- <vbox id="summary_box"/>
- <hbox>
- <hbox id="marc_cn"/>
- <spacer flex="1" />
- <button id="generate_barcodes" label="&staff.cat.volume_copy_creator.generate_barcodes.label;" oncommand="g.generate_barcodes();" accesskey="&staff.cat.volume_copy_creator.generate_barcodes.accesskey;"/>
- <checkbox id="check_barcodes" label="&staff.cat.volume_copy_creator.check_barcodes.label;" oncommand="g.save_prefs();" accesskey="&staff.cat.volume_copy_creator.check_barcodes.accesskey;"/>
- <checkbox id="print_labels" label="&staff.cat.volume_copy_creator.print_labels.label;" oncommand="g.save_prefs();" accesskey="&staff.cat.volume_copy_creator.print_labels.accesskey;"/>
- </hbox>
- <groupbox flex="1" class="my_overflow">
- <caption id="caption" label="&staff.cat.volume_copy_creator.label;"/>
- <grid flex="1">
- <columns> <column flex="0"/> <column flex="0"/> <column flex="1"/> </columns>
- <rows id="rows">
- <row>
- <label value="&staff.cat.volume_copy_creator.library_label.value;" style="font-weight: bold"/>
- <label value="&staff.cat.volume_copy_creator.num_of_volumes_label.value;" style="font-weight: bold"/>
- </row>
- </rows>
- </grid>
- </groupbox>
- <hbox style="border-bottom: solid black thin">
- <spacer flex="1" />
- <button id="CreateWithDefaults" disabled="true" oncommand="g.stash_and_close('noedit');"/>
- <button id="EditThenCreate" disabled="true" oncommand="g.stash_and_close('edit');"/>
- </hbox>
+<vbox flex="1" class="my_overflow">
+ <vbox id="summary_box" oils_persist="height"/>
+ <splitter
+ collapse="before"
+ resize_before="flex"
+ resize_after="flex"
+ oils_persist="state hidden"
+ oils_persist_peers="summary_box main">
+ <grippy/>
+ </splitter>
+ <vbox id="main" oils_persist="height" flex="1">
+ <hbox flex="0">
+ <hbox id="batch_bar">
+ <label value="&staff.cat.volume_copy_creator.batch_bar;"/>
+ <label value="&staff.cat.volume_copy_creator.batch_bar.call_number.classification;"/>
+ <hbox id="batch_class"/>
+ <label value="&staff.cat.volume_copy_creator.batch_bar.call_number.prefix;"/>
+ <hbox id="batch_prefix"/>
+ <label value="&staff.cat.volume_copy_creator.batch_bar.call_number.label.label;"
+ accesskey="&staff.cat.volume_copy_creator.batch_bar.call_number.label.accesskey;" control="marc_cn_menulist"/>
+ <hbox id="marc_cn"/>
+ <label value="&staff.cat.volume_copy_creator.batch_bar.call_number.suffix;"/>
+ <hbox id="batch_suffix"/>
+ <hbox id="batch_button_box"/>
+ </hbox>
+ <spacer flex="1" />
+ </hbox>
+ <groupbox flex="1" class="my_overflow">
+ <caption id="caption" label="&staff.cat.volume_copy_creator.label;"/>
+ <grid flex="1">
+ <columns> <column flex="0"/> <column flex="0"/> <column flex="1"/> </columns>
+ <rows id="rows">
+ <row>
+ <label value="&staff.cat.volume_copy_creator.library_label.value;" style="font-weight: bold"/>
+ <label value="&staff.cat.volume_copy_creator.num_of_volumes_label.value;" style="font-weight: bold"/>
+ </row>
+ </rows>
+ </grid>
+ </groupbox>
+ <hbox style="border-bottom: solid black thin" flex="0">
+ <hbox id="misc_control_bar">
+ <button id="generate_barcodes"
+ label="&staff.cat.volume_copy_creator.generate_barcodes.label;"
+ oncommand="g.generate_barcodes();"
+ accesskey="&staff.cat.volume_copy_creator.generate_barcodes.accesskey;"/>
+ <checkbox id="check_barcodes"
+ label="&staff.cat.volume_copy_creator.check_barcodes.label;"
+ oncommand="g.save_prefs();"
+ accesskey="&staff.cat.volume_copy_creator.check_barcodes.accesskey;"/>
+ <checkbox id="print_labels"
+ label="&staff.cat.volume_copy_creator.print_labels.label;"
+ oncommand="g.save_prefs();"
+ accesskey="&staff.cat.volume_copy_creator.print_labels.accesskey;"/>
+ </hbox>
+ <spacer flex="1"/>
+ <hbox id="non_unified_buttons">
+ <button id="CreateWithDefaults" disabled="true" oncommand="g.stash_and_close('noedit');"/>
+ <button id="EditThenCreate" disabled="true" oncommand="g.stash_and_close('edit');"/>
+ </hbox>
+ <button id="Create" disabled="true" oncommand="g.stash_and_close('unified_interface');"/>
+ </hbox>
+ </vbox>
+</vbox>
</window>
--- /dev/null
+var error;
+var g = {};
+
+function my_init() {
+ try {
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+ if (typeof JSAN == 'undefined') { throw( "The JSAN library object is missing."); }
+ JSAN.errorLevel = "die"; // none, warn, or die
+ JSAN.addRepository('/xul/server/');
+ JSAN.use('util.error'); error = new util.error();
+ error.sdump('D_TRACE','my_init() for main_test.xul');
+
+ /*if (typeof window.xulG == 'object' && typeof window.xulG.set_tab_name == 'function') {
+ try { window.xulG.set_tab_name('Test'); } catch(E) { alert(E); }
+ }*/
+
+ // Both interfaces look for this
+ xulG.unified_interface = true;
+
+ // Item Attribute Editor looks for these
+ xulG.not_modal = true;
+ xulG.edit = true;
+
+ // Spawn the volume/copy creator
+ JSAN.use('util.browser');
+ var volume_pane = new util.browser();
+ volume_pane.init(
+ {
+ 'url' : urls.XUL_VOLUME_COPY_CREATOR_ORIGINAL,
+ 'push_xulG' : true,
+ 'alt_print' : false,
+ 'browser_id' : 'volume_pane',
+ 'passthru_content_params' : xulG
+ }
+ );
+
+ setup_templates();
+
+ // Spawn the item attribute editor
+ var item_pane = new util.browser();
+ item_pane.init(
+ {
+ 'url' : urls.XUL_COPY_EDITOR,
+ 'push_xulG' : true,
+ 'alt_print' : false,
+ 'browser_id' : 'item_pane',
+ 'passthru_content_params' : xulG,
+ 'on_url_load' : g.clone_template_bar // from setup_templates()
+ }
+ );
+
+ } catch(E) {
+ alert('Error in volume_copy_editor.js, my_init(): ' + E);
+ }
+}
+
+function setup_templates() {
+ try {
+ JSAN.use('util.widgets'); JSAN.use('util.functional');
+
+ // Once the item attribute editor is loaded, clone and import its template menu to this window with this callback
+ g.clone_template_bar = function() {
+ var item_editor_template_bar = get_contentWindow( $('item_pane') ).document.getElementById('template_bar');
+ $('template_bar_holder').appendChild(
+ document.importNode(
+ item_editor_template_bar,
+ true // children
+ )
+ );
+ item_editor_template_bar.hidden = true;
+ g.apply_template = function() {
+ xulG.update_item_editor_template_selection( $('template_menu').value );
+ xulG.item_editor_apply_template();
+ };
+ g.delete_template = function() {
+ xulG.update_item_editor_template_selection( $('template_menu').value );
+ xulG.item_editor_delete_template();
+ };
+ g.save_template = function() { xulG.item_editor_save_template(); };
+ g.import_templates = function() { xulG.item_editor_import_templates(); };
+ g.export_templates = function() { xulG.item_editor_apply_templates(); };
+ g.reset = function() { xulG.item_editor_reset(); };
+
+ // just do this once; not sure if on_url_load could fire multiple times
+ g.clone_template_bar = function() {};
+ }
+
+ // callback for populating the list of templates
+ xulG.update_unified_template_list = function(list) {
+ try {
+ util.widgets.remove_children('template_placeholder');
+ g.template_menu = util.widgets.make_menulist( list );
+ g.template_menu.setAttribute('id','template_menu');
+ $('template_placeholder').appendChild(g.template_menu);
+ g.template_menu.addEventListener(
+ 'command',
+ function() {
+ xulG.update_item_editor_template_selection( g.template_menu.value );
+ },
+ false
+ );
+ } catch(E) {
+ alert('Error in volume_copy_editor.js, xulG.update_unified_template_list(): ' + E);
+ }
+ };
+
+ } catch(E) {
+ alert('Error in volume_copy_editor.js, setup_templates(): ' + E);
+ }
+}
+
--- /dev/null
+<?xml version="1.0"?>
+<!-- Application: Evergreen Staff Client -->
+<!-- Screen: Unified Call Number / Item Editor/Creator -->
+
+<!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
+<!-- STYLESHEETS -->
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="/xul/server/skin/global.css" type="text/css"?>
+
+<!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
+<!-- LOCALIZATION -->
+<!DOCTYPE window PUBLIC "" ""[
+ <!--#include virtual="/opac/locale/${locale}/lang.dtd"-->
+]>
+
+<!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
+<!-- OVERLAYS -->
+<?xul-overlay href="/xul/server/OpenILS/util_overlay.xul"?>
+
+<window id="volume_item_win"
+ onload="try { my_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
+ <!-- BEHAVIOR -->
+ <script type="text/javascript">
+ var myPackageDir = 'open_ils_staff_client'; var IAMXUL = true;
+ </script>
+ <scripts id="openils_util_scripts"/>
+
+ <script type="text/javascript" src="/xul/server/main/JSAN.js"/>
+ <script type="text/javascript" src="volume_copy_editor.js"/>
+
+ <vbox flex="1">
+ <vbox id="top_pane" flex="1" oils_persist="height">
+ <hbox id="template_bar_holder"/>
+ <browser id="volume_pane" flex="1" />
+ </vbox>
+ <splitter
+ collapse="after"
+ resizeafter="flex"
+ resizebefore="flex"
+ oils_persist="state hidden"
+ oils_persist_peers="top_pane bottom_pane">
+ <grippy/>
+ </splitter>
+ <vbox id="bottom_pane" flex="1" oils_persist="height">
+ <browser id="item_pane" flex="1" />
+ <hbox id="bottom_bar"/>
+ </vbox>
+ </vbox>
+
+</window>
+
--- /dev/null
+<?xml version="1.0"?>
+<!-- Application: Evergreen Staff Client -->
+<!-- Screen: Unified Call Number / Item Editor/Creator -->
+
+<!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
+<!-- STYLESHEETS -->
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="/xul/server/skin/global.css" type="text/css"?>
+
+<!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
+<!-- LOCALIZATION -->
+<!DOCTYPE window PUBLIC "" ""[
+ <!--#include virtual="/opac/locale/${locale}/lang.dtd"-->
+]>
+
+<!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
+<!-- OVERLAYS -->
+<?xul-overlay href="/xul/server/OpenILS/util_overlay.xul"?>
+
+<window id="volume_item_win"
+ onload="try { my_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
+ <!-- BEHAVIOR -->
+ <script type="text/javascript">
+ var myPackageDir = 'open_ils_staff_client'; var IAMXUL = true;
+ </script>
+ <scripts id="openils_util_scripts"/>
+
+ <script type="text/javascript" src="/xul/server/main/JSAN.js"/>
+ <script type="text/javascript" src="volume_copy_editor.js"/>
+
+ <hbox flex="1">
+ <vbox id="top_pane" flex="1" oils_persist="width">
+ <hbox id="template_bar_holder"/>
+ <browser id="volume_pane" flex="1" />
+ </vbox>
+ <splitter
+ collapse="after"
+ resizeafter="flex"
+ resizebefore="flex"
+ oils_persist="state hidden"
+ oils_persist_peers="top_pane bottom_pane">
+ <grippy/>
+ </splitter>
+ <vbox id="bottom_pane" flex="1" oils_persist="width">
+ <browser id="item_pane" flex="1" />
+ <hbox id="bottom_bar"/>
+ </vbox>
+ </hbox>
+
+</window>
+
--- /dev/null
+var xulG = {};
+
+function my_init() {
+ try {
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+ if (typeof JSAN == 'undefined') { throw( $("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 cat/volume_editor.xul');
+
+ JSAN.use('OpenILS.data'); g.data = new OpenILS.data(); g.data.init({'via':'stash'});
+ JSAN.use('util.network'); g.network = new util.network();
+
+ JSAN.use('util.functional');
+
+ g.volumes = xul_param('volumes',{'stash_name':'volumes_temp','clear_xpcom':true,'modal_xulG':true}); //JSON2js( g.data.volumes_temp );
+ //g.data.volumes_temp = ''; g.data.stash('volumes_temp');
+
+ var rows = document.getElementById('rows');
+
+ var first_tb;
+
+ for (var i = 0; i < g.volumes.length; i++) {
+ var row = document.createElement('row'); rows.appendChild(row);
+ var lib_label = document.createElement('label'); row.appendChild(lib_label);
+ var class_ml = g.render_class_menu(i); row.appendChild(class_ml);
+ var prefix_ml = g.render_prefix_menu(i); row.appendChild(prefix_ml);
+ var label_tb = document.createElement('textbox'); row.appendChild(label_tb);
+ var suffix_ml = g.render_suffix_menu(i); row.appendChild(suffix_ml);
+ if (!first_tb) { first_tb = label_tb; }
+
+ var lib_id = g.volumes[i].owning_lib();
+ var last_lib_seen;
+
+ if (last_lib_seen != lib_id ) {
+ lib_label.setAttribute('value',g.data.hash.aou[ lib_id ].shortname() );
+ last_lib_seen = lib_id;
+ }
+
+ label_tb.setAttribute('value',g.volumes[i].label());
+ label_tb.setAttribute('onchange','try { var v = g.volumes['+i+']; v.ischanged("1"); v.label( this.value ); } catch(E) { alert(E); }');
+ }
+
+ first_tb.select(); first_tb.focus();
+
+ } catch(E) {
+ var err_msg = $("commonStrings").getFormattedString('common.exception', ['cat/volume_editor.xul', E]);
+ try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); dump(js2JSON(E)); }
+ alert(err_msg);
+ }
+}
+
+g.stash_and_close = function() {
+ try {
+ //g.data.volumes_temp = js2JSON( g.volumes );
+ //g.error.sdump('D_CAT','in modal window, g.data.volumes_temp = \n' + g.data.volumes_temp + '\n');
+ //g.data.stash('volumes_temp');
+ xulG.volumes = g.volumes;
+ xulG.update_these_volumes = 1;
+ xulG.auto_merge = document.getElementById('auto_merge').checked;
+ update_modal_xulG(xulG);
+ window.close();
+ } catch(E) {
+ alert('FIXME: volume editor -> ' + E);
+ }
+}
+
+g.render_class_menu = function(vol_idx) {
+ var ml = util.widgets.make_menulist(
+ util.functional.map_list(
+ g.data.list.acnc,
+ function(o) {
+ return [ o.name(), o.id() ];
+ }
+ ),
+ typeof g.volumes[vol_idx].label_class() == 'object'
+ ? g.volumes[vol_idx].label_class().id()
+ : g.volumes[vol_idx].label_class()
+ );
+ ml.addEventListener(
+ 'command',
+ function(ev) {
+ g.volumes[vol_idx].ischanged(1);
+ g.volumes[vol_idx].label_class(ml.value);
+ },
+ false
+ );
+ return ml;
+}
+
+g.render_prefix_menu = function(vol_idx) {
+ var org = typeof g.volumes[vol_idx].owning_lib() == 'object'
+ ? g.volumes[vol_idx].owning_lib()
+ : g.data.hash.aou[ g.volumes[vol_idx].owning_lib() ];
+ var menulist = document.createElement('menulist');
+ var menupopup = document.createElement('menupopup');
+ menulist.appendChild(menupopup);
+ var org_list = []; // order from top of consortium to owning lib
+ while(org) {
+ org_list.unshift(org.id());
+ org = org.parent_ou();
+ if (org && typeof org != 'object') {
+ org = g.data.hash.aou[ org ];
+ }
+ }
+ for (var i = 0; i < org_list.length; i++) {
+ g.render_prefix_menu_items(menupopup,org_list[i]);
+ }
+ menulist.setAttribute('value',
+ typeof g.volumes[vol_idx].prefix() == 'object'
+ ? g.volumes[vol_idx].prefix().id()
+ : g.volumes[vol_idx].prefix()
+ );
+
+ menulist.addEventListener(
+ 'command',
+ function() {
+ g.volumes[vol_idx].ischanged(1);
+ g.volumes[vol_idx].prefix(menulist.value);
+ },
+ false
+ );
+ return menulist;
+}
+
+g.render_prefix_menu_items = function(menupopup,ou_id) {
+ if (typeof g.data.list['acnp_for_lib_'+ou_id] == 'undefined') {
+ g.data.list['acnp_for_lib_'+ou_id] = g.network.simple_request(
+ 'FM_ACNP_RETRIEVE_VIA_PCRUD',
+ [ ses(), {"owning_lib":{"=":ou_id}}, {"order_by":{"acnp":"label_sortkey"}} ]
+ );
+ g.data.stash('list');
+ }
+ for (var i = 0; i < g.data.list['acnp_for_lib_'+ou_id].length; i++) {
+ var my_acnp = g.data.list['acnp_for_lib_'+ou_id][i];
+ var menuitem = document.createElement('menuitem');
+ menupopup.appendChild(menuitem);
+ menuitem.setAttribute(
+ 'label',
+ my_acnp.id() == -1 ? '' :
+ $('catStrings').getFormattedString(
+ 'staff.cat.volume_copy_creator.call_number_prefix.menuitem_label',
+ [
+ my_acnp.label(),
+ g.data.hash.aou[ ou_id ].shortname()
+ ]
+ )
+ );
+ menuitem.setAttribute('value',my_acnp.id());
+ }
+}
+
+
+g.render_suffix_menu = function(vol_idx) {
+ var org = typeof g.volumes[vol_idx].owning_lib() == 'object'
+ ? g.volumes[vol_idx].owning_lib()
+ : g.data.hash.aou[ g.volumes[vol_idx].owning_lib() ];
+ var menulist = document.createElement('menulist');
+ var menupopup = document.createElement('menupopup');
+ menulist.appendChild(menupopup);
+ var org_list = []; // order from top of consortium to owning lib
+ while(org) {
+ org_list.unshift(org.id());
+ org = org.parent_ou();
+ if (org && typeof org != 'object') {
+ org = g.data.hash.aou[ org ];
+ }
+ }
+ for (var i = 0; i < org_list.length; i++) {
+ g.render_suffix_menu_items(menupopup,org_list[i]);
+ }
+ menulist.setAttribute('value',
+ typeof g.volumes[vol_idx].suffix() == 'object'
+ ? g.volumes[vol_idx].suffix().id()
+ : g.volumes[vol_idx].suffix()
+ );
+
+ menulist.addEventListener(
+ 'command',
+ function() {
+ g.volumes[vol_idx].ischanged(1);
+ g.volumes[vol_idx].suffix(menulist.value);
+ },
+ false
+ );
+ return menulist;
+}
+
+g.render_suffix_menu_items = function(menupopup,ou_id) {
+ if (typeof g.data.list['acns_for_lib_'+ou_id] == 'undefined') {
+ g.data.list['acns_for_lib_'+ou_id] = g.network.simple_request(
+ 'FM_ACNS_RETRIEVE_VIA_PCRUD',
+ [ ses(), {"owning_lib":{"=":ou_id}}, {"order_by":{"acns":"label_sortkey"}} ]
+ );
+ g.data.stash('list');
+ }
+ for (var i = 0; i < g.data.list['acns_for_lib_'+ou_id].length; i++) {
+ var my_acns = g.data.list['acns_for_lib_'+ou_id][i];
+ var menuitem = document.createElement('menuitem');
+ menupopup.appendChild(menuitem);
+ menuitem.setAttribute(
+ 'label',
+ my_acns.id() == -1 ? '' :
+ $('catStrings').getFormattedString(
+ 'staff.cat.volume_copy_creator.call_number_suffix.menuitem_label',
+ [
+ my_acns.label(),
+ g.data.hash.aou[ ou_id ].shortname()
+ ]
+ )
+ );
+ menuitem.setAttribute('value',my_acns.id());
+ }
+}
+
+
<window id="cat_volume_editor_win"
onload="try { my_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
- title="&staff.cat.volume_editor.title;" height="400" width="300" oils_persist="height width"
+ title="&staff.cat.volume_editor.title;" height="800" width="300" oils_persist="height width"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
<scripts id="openils_util_scripts"/>
<script type="text/javascript" src="/xul/server/main/JSAN.js"/>
- <script>
- <![CDATA[
+ <script type="text/javascript" src="volume_editor.js"/>
- var xulG = {};
-
- function my_init() {
- try {
- netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
- if (typeof JSAN == 'undefined') { throw( $("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 cat/volume_editor.xul');
-
- JSAN.use('OpenILS.data'); g.data = new OpenILS.data(); g.data.init({'via':'stash'});
-
- JSAN.use('util.functional');
-
- g.volumes = xul_param('volumes',{'stash_name':'volumes_temp','clear_xpcom':true,'modal_xulG':true}); //JSON2js( g.data.volumes_temp );
- //g.data.volumes_temp = ''; g.data.stash('volumes_temp');
-
- var rows = document.getElementById('rows');
-
- var first_tb;
-
- for (var i = 0; i < g.volumes.length; i++) {
- var row = document.createElement('row'); rows.appendChild(row);
- var lib_label = document.createElement('label'); row.appendChild(lib_label);
- var tb = document.createElement('textbox'); row.appendChild(tb);
- if (!first_tb) { first_tb = tb; }
-
- var lib_id = g.volumes[i].owning_lib();
- var last_lib_seen;
-
- if (last_lib_seen != lib_id ) {
- lib_label.setAttribute('value',g.data.hash.aou[ lib_id ].shortname() );
- last_lib_seen = lib_id;
- }
-
- tb.setAttribute('value',g.volumes[i].label());
- tb.setAttribute('onchange','try { var v = g.volumes['+i+']; v.ischanged("1"); v.label( this.value ); } catch(E) { alert(E); }');
- }
-
- first_tb.select(); first_tb.focus();
-
- } catch(E) {
- var err_msg = $("commonStrings").getFormattedString('common.exception', ['cat/volume_editor.xul', E]);
- try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); dump(js2JSON(E)); }
- alert(err_msg);
- }
- }
-
- g.stash_and_close = function() {
- try {
- //g.data.volumes_temp = js2JSON( g.volumes );
- //g.error.sdump('D_CAT','in modal window, g.data.volumes_temp = \n' + g.data.volumes_temp + '\n');
- //g.data.stash('volumes_temp');
- xulG.volumes = g.volumes;
- xulG.update_these_volumes = 1;
- xulG.auto_merge = document.getElementById('auto_merge').checked;
- update_modal_xulG(xulG);
- window.close();
- } catch(E) {
- alert('FIXME: volume editor -> ' + E);
- }
- }
-
- ]]>
- </script>
-
<messagecatalog id="catStrings" src="/xul/server/locale/<!--#echo var='locale'-->/cat.properties" />
<messagecatalog id="circStrings" src="/xul/server/locale/<!--#echo var='locale'-->/circ.properties" />
<checkbox id="auto_merge" label="&staff.cat.volume_editor.automerge.label;" accesskey="&staff.cat.volume_editor.automerge.accesskey;" oils_persist="checked"/>
</hbox>
<grid flex="1">
- <columns> <column /> <column /> <column flex="1"/> </columns>
- <rows id="rows" />
+ <columns>
+ <column />
+ <column />
+ <column />
+ <column flex="1"/>
+ <column />
+ </columns>
+ <rows id="rows">
+ <row>
+ <label value="&staff.cat.volume_editor.owning_lib;" class="header"/>
+ <label value="&staff.cat.volume_editor.classification;" class="header"/>
+ <label value="&staff.cat.volume_editor.prefix;" class="header"/>
+ <label value="&staff.cat.volume_editor.label;" class="header"/>
+ <label value="&staff.cat.volume_editor.suffix;" class="header"/>
+ </row>
+ </rows>
</grid>
</groupbox>
var title = document.getElementById('circStrings').getFormattedString('staff.circ.copy_status.add_items.title', [r]);
+ var horizontal_interface = String( obj.data.hash.aous['ui.cat.volume_copy_editor.horizontal'] ) == 'true';
+ var url = window.xulG.url_prefix( horizontal_interface ? urls.XUL_VOLUME_COPY_CREATOR_HORIZONTAL : urls.XUL_VOLUME_COPY_CREATOR );
var w = xulG.new_tab(
- window.xulG.url_prefix(urls.XUL_VOLUME_COPY_CREATOR),
+ url,
{ 'tab_name' : title },
{ 'doc_id' : r, 'ou_ids' : list, 'copy_shortcut' : copy_shortcut[r] }
);
var title = document.getElementById('circStrings').getFormattedString('staff.circ.copy_status.add_volumes.title', [r]);
+ var horizontal_interface = String( obj.data.hash.aous['ui.cat.volume_copy_editor.horizontal'] ) == 'true';
+ var url = window.xulG.url_prefix( horizontal_interface ? urls.XUL_VOLUME_COPY_CREATOR_HORIZONTAL : urls.XUL_VOLUME_COPY_CREATOR );
var w = xulG.new_tab(
- window.xulG.url_prefix(urls.XUL_VOLUME_COPY_CREATOR),
+ url,
{ 'tab_name' : title },
{ 'doc_id' : r, 'ou_ids' : list }
);
'flex' : 1,
'primary' : false,
'hidden' : true,
- 'editable' : false, 'render' : function(my) {
- if (my.acp && my.acp.call_number() == -1) {
+ 'editable' : false, 'render' : function(my,scratch_data) {
+ var acn_id;
+ if (my.acn) {
+ if (typeof my.acn == 'object') {
+ acn_id = my.acn.id();
+ } else {
+ acn_id = my.acn;
+ }
+ } else if (my.acp) {
+ if (typeof my.acp.call_number() == 'object') {
+ acn_id = my.acp.call_number().id();
+ } else {
+ acn_id = my.acp.call_number();
+ }
+ }
+ if (!acn_id && acn_id != 0) {
+ return '';
+ } else if (acn_id == -1) {
return document.getElementById('circStrings').getString('staff.circ.utils.not_cataloged');
- } else if (my.acp && my.acp.call_number() == -2) {
+ } else if (acn_id == -2) {
return document.getElementById('circStrings').getString('staff.circ.utils.retrieving');
} else {
if (!my.acn) {
- var x = network.simple_request("FM_ACN_RETRIEVE.authoritative",[ my.acp.call_number() ]);
- if (x.ilsevent) {
- return document.getElementById('circStrings').getString('staff.circ.utils.not_cataloged');
+ if (typeof scratch_data['acn_map'] == 'undefined') {
+ scratch_data['acn_map'] = {};
+ }
+ if (typeof scratch_data['acn_map'][ acn_id ] == 'undefined') {
+ var x = network.simple_request("FM_ACN_RETRIEVE.authoritative",[ acn_id ]);
+ if (x.ilsevent) {
+ return document.getElementById('circStrings').getString('staff.circ.utils.not_cataloged');
+ } else {
+ my.acn = x;
+ scratch_data['acn_map'][ acn_id ] = my.acn;
+ }
} else {
- my.acn = x; return x.label();
+ my.acn = scratch_data['acn_map'][ acn_id ];
}
- } else {
- return my.acn.label();
}
+ return my.acn.label();
}
},
'persist' : 'hidden width ordinal'
'persist' : 'hidden width ordinal'
},
{
+ 'id' : 'prefix',
+ 'fm_class' : 'acn',
+ 'label' : document.getElementById('circStrings').getString('staff.circ.utils.prefix'),
+ 'flex' : 1,
+ 'primary' : false,
+ 'hidden' : true,
+ 'editable' : false, 'render' : function(my) {
+ if (typeof my.acn == 'undefined') return '';
+ return (typeof my.acn.prefix() == 'object') ? my.acn.prefix().label() : my.acn.prefix();
+ },
+ 'persist' : 'hidden width ordinal'
+ },
+ {
+ 'id' : 'suffix',
+ 'fm_class' : 'acn',
+ 'label' : document.getElementById('circStrings').getString('staff.circ.utils.suffix'),
+ 'flex' : 1,
+ 'primary' : false,
+ 'hidden' : true,
+ 'editable' : false, 'render' : function(my) {
+ if (typeof my.acn == 'undefined') return '';
+ return (typeof my.acn.suffix() == 'object') ? my.acn.suffix().label() : my.acn.suffix();
+ },
+ 'persist' : 'hidden width ordinal'
+ },
+ {
+ 'id' : 'label_class',
+ 'fm_class' : 'acn',
+ 'label' : document.getElementById('circStrings').getString('staff.circ.utils.label_class'),
+ 'flex' : 1,
+ 'primary' : false,
+ 'hidden' : true,
+ 'editable' : false, 'render' : function(my) {
+ if (typeof my.acn == 'undefined') return '';
+ return (typeof my.acn.label_class() == 'object') ? my.acn.label_class().name() : my.acn.label_class();
+ },
+ 'persist' : 'hidden width ordinal'
+ },
+ {
+ 'id' : 'parts',
+ 'fm_class' : 'acp',
+ 'label' : document.getElementById('commonStrings').getString('staff.acp_label_parts'),
+ 'flex' : 1,
+ 'sort_type' : 'number',
+ 'primary' : false,
+ 'hidden' : true,
+ 'editable' : false, 'render' : function(my) {
+ if (! my.acp.parts()) return '';
+ var parts = my.acp.parts();
+ var display_string = '';
+ for (var i = 0; i < parts.length; i++) {
+ if (my.doc_id) {
+ if (my.doc_id == parts[i].record()) {
+ return parts[i].label();
+ }
+ } else {
+ if (i != 0) display_string += ' : ';
+ display_string += parts[i].label();
+ }
+ }
+ return display_string;
+ },
+ 'persist' : 'hidden width ordinal'
+ },
+ {
'id' : 'copy_number',
'fm_class' : 'acp',
'label' : document.getElementById('commonStrings').getString('staff.acp_label_copy_number'),
};
*/
circ.util.std_map_row_to_columns = function(error_value) {
- return function(row,cols) {
+ return function(row,cols,scratch) {
// row contains { 'my' : { 'acp' : {}, 'circ' : {}, 'mvr' : {} } }
// cols contains all of the objects listed above in columns
+ // scratch is a temporary space shared by all cells/rows (or just per row if not explicitly passed in)
+ if (!scratch) { scratch = {}; }
var obj = {};
JSAN.use('util.error'); obj.error = new util.error();
try {
for (var i = 0; i < cols.length; i++) {
switch (typeof cols[i].render) {
- case 'function': try { values[i] = cols[i].render(my); } catch(E) { values[i] = error_value; obj.error.sdump('D_COLUMN_RENDER_ERROR',E); } break;
+ case 'function': try { values[i] = cols[i].render(my,scratch); } catch(E) { values[i] = error_value; obj.error.sdump('D_COLUMN_RENDER_ERROR',E); } break;
case 'string' : cmd += 'try { ' + cols[i].render + '; values['+i+'] = v; } catch(E) { values['+i+'] = error_value; }'; break;
default: cmd += 'values['+i+'] = "??? '+(typeof cols[i].render)+'"; ';
}
staff.cat.copy_browser.delete_volume.cancel=Cancel
staff.cat.copy_browser.delete_volume.override=Override Delete Failure?
staff.cat.copy_browser.delete_volume.copies_remain=You must delete all the copies on the volume before you may delete the volume itself.
-staff.cat.copy_browser.delete_volume.success=Volumes deleted.
staff.cat.copy_browser.delete_volume.exception=copy browser -> delete volumes
staff.cat.copy_browser.mark_library.alert=Library + Record marked as Volume Transfer Destination
staff.cat.copy_browser.mark_library.prompt=Choose just one Library to mark as Volume Transfer Destination
staff.cat.volume_buckets.window_tab_name=Volume Buckets
staff.cat.volume_copy_creator.my_init.btn.label=Apply
staff.cat.volume_copy_creator.my_init.btn.accesskey=A
+staff.cat.volume_copy_creator.create_part.btn.label=Create Part Designator
staff.cat.volume_copy_creator.edit_then_create.btn.label=Edit then Create
staff.cat.volume_copy_creator.edit_then_create.btn.accesskey=C
staff.cat.volume_copy_creator.create_with_defaults.btn.label=Create with Defaults
staff.cat.volume_copy_creator.create_with_defaults.btn.accesskey=D
+staff.cat.volume_copy_creator.create.btn.label=Create Volumes/Items
+staff.cat.volume_copy_creator.create.btn.accesskey=C
staff.cat.volume_copy_creator.edit_then_rebarcode.btn.label=Edit then Re-barcode
staff.cat.volume_copy_creator.edit_then_rebarcode.btn.accesskey=E
-staff.cat.volume_copy_creator.rebarcode.btn.label=Re-barcode
+staff.cat.volume_copy_creator.rebarcode.btn.label=Re-barcode / Update Items
staff.cat.volume_copy_creator.rebarcode.btn.accesskey=R
staff.cat.volume_copy_creator.render_volume_count_entry.message=You may not add more than %1$s items at a time for a given volume in this interface.
staff.cat.volume_copy_creator.render_volume_count_entry.title=Maximum items exceeded.
staff.cat.volume_copy_creator.render_volume_count_entry.ok_label=Ok
+staff.cat.volume_copy_creator.render_callnumber_copy_count_entry.classification=Classification
+staff.cat.volume_copy_creator.render_callnumber_copy_count_entry.prefix=Prefix
staff.cat.volume_copy_creator.render_callnumber_copy_count_entry.call_nums=Call Numbers
+staff.cat.volume_copy_creator.render_callnumber_copy_count_entry.suffix=Suffix
staff.cat.volume_copy_creator.render_callnumber_copy_count_entry.num_of_copies=# of Copies
+staff.cat.volume_copy_creator.render_callnumber_copy_count_entry.barcodes_and_parts=Barcodes / Part Designation
staff.cat.volume_copy_creator.render_barcode_entry.alert_message="%1$s" is an invalid barcode.
staff.cat.volume_copy_creator.render_barcode_entry.alert_title=Invalid Barcode
staff.cat.volume_copy_creator.render_barcode_entry.alert_ok_button=OK
staff.cat.volume_copy_creator.stash_and_close.tree_err3=volume tree update 3
staff.cat.volume_copy_creator.load_prefs.err_retrieving_prefs=Error retrieving stored preferences
staff.cat.volume_copy_creator.save_prefs.err_storing_prefs=Error storing preferences
+# %1$s = Call Number Prefix Label, %2$s = Call Number Prefix Owning Lib Shortname
+staff.cat.volume_copy_creator.call_number_prefix.menuitem_label=%2$s : %1$s
+# %1$s = Call Number Suffix Label, %2$s = Call Number Suffix Owning Lib Shortname
+staff.cat.volume_copy_creator.call_number_suffix.menuitem_label=%2$s : %1$s
staff.cat.z3950.native_catalog=Native Catalog
staff.cat.z3950.obj_list_init.list_construction_error=Failure during list construction.
staff.cat.z3950.results_view.label=Results View
staff.circ.utils.not_cataloged=Not Cataloged
staff.circ.utils.retrieving=Retrieving...
staff.circ.utils.owning_lib=Owning Library
+staff.circ.utils.prefix=Prefix
+staff.circ.utils.suffix=Suffix
+staff.circ.utils.label_class=Classification
staff.circ.utils.loan_duration.short=Short
staff.circ.utils.loan_duration.normal=Normal
staff.circ.utils.loan_duration.long=Long
# %1$s = circ modifier code, %2$s = circ modifier name, %3$s = circ modifier description
staff.circ_modifier.display=%1$s : %2$s : %3$s
staff.acp_label_copy_number=Copy Number
+staff.acp_label_parts=Part
staff.acp_label_deposit_amount=Deposit Amount
staff.acp_label_fine_level=Fine Level
staff.acp_label_id=Copy ID
}
patron.util.std_map_row_to_columns = function(error_value) {
- return function(row,cols) {
+ return function(row,cols,scratch) {
// row contains { 'my' : { 'au' : {} } }
// cols contains all of the objects listed above in columns
+ // scratch is a temporary space shared by all cells/rows (or just per row if not explicitly passed in)
var obj = {}; obj.OpenILS = {};
JSAN.use('util.error'); obj.error = new util.error();