return $resp;
}
+__PACKAGE__->register_method(
+ method => 'stream_wide_holds',
+ authoritative => 1,
+ stream => 1,
+ api_name => 'open-ils.circ.hold.wide_hash.stream'
+);
+
+sub stream_wide_holds {
+ my($self, $client, $auth, $restrictions, $order_by, $limit, $offset) = @_;
+
+ my $e = new_editor(authtoken=>$auth);
+ $e->checkauth or return $e->event;
+ $e->allowed('VIEW_HOLD') or return $e->event;
+
+ my $st = OpenSRF::AppSession->create('open-ils.storage');
+ my $req = $st->request(
+ 'open-ils.storage.action.live_holds.wide_hash',
+ $restrictions, $order_by, $limit, $offset
+ );
+
+ my $count = $req->recv;
+ if(!$count) {
+ return 0;
+ }
+
+ if(UNIVERSAL::isa($count,"Error")) {
+ throw $count ($count->stringify);
+ }
+
+ $count = $count->content;
+
+ # Force immediate send of count response
+ my $mbc = $client->max_bundle_count;
+ $client->max_bundle_count(1);
+ $client->respond($count);
+ $client->max_bundle_count($mbc);
+
+ while (my $hold = $req->recv) {
+ $client->respond($hold->content) if $hold->content;
+ }
+
+ $client->respond_complete;
+}
}
+sub wide_hold_data {
+ my $self = shift;
+ my $client = shift;
+ my $restrictions = shift; # hashref of field restrictions {f1=>undef,f2=>[1,2,3],f3=>'foo',f4=>{not=>undef}}
+ my $order_by = shift; # arrayref of hashrefs of ORDER BY clause, [{field =>{dir=>'desc',nulls=>'last'}}]
+ my $limit = shift;
+ my $offset = shift;
+
+ $order_by = [$order_by] if (ref($order_by) !~ /ARRAY/);
+
+ $log->info('Received '. keys(%$restrictions) .' restrictions');
+ return 0 unless (ref $restrictions and keys %$restrictions);
+
+ # force this to either 'true' or 'false'
+ my $is_staff_request = delete($$restrictions{is_staff_request}) || 'false';
+ $is_staff_request = 'false' if (!grep {$is_staff_request eq $_} qw/true false/);
+ $log->info('is_staff_request: '. $is_staff_request);
+
+ my $select = <<" SQL";
+WITH
+ t_field AS (SELECT field FROM config.display_field_map WHERE name = 'title'),
+ a_field AS (SELECT field FROM config.display_field_map WHERE name = 'author')
+SELECT h.id, h.request_time, h.capture_time, h.fulfillment_time, h.checkin_time,
+ h.return_time, h.prev_check_time, h.expire_time, h.cancel_time, h.cancel_cause,
+ h.cancel_note, h.target, h.current_copy, h.fulfillment_staff, h.fulfillment_lib,
+ h.request_lib, h.requestor, h.usr, h.selection_ou, h.selection_depth, h.pickup_lib,
+ h.hold_type, h.holdable_formats, h.phone_notify, h.email_notify, h.sms_notify,
+ h.sms_carrier, h.frozen, h.thaw_date, h.shelf_time, h.cut_in_line, h.mint_condition,
+ h.shelf_expire_time, h.current_shelf_lib, h.behind_desk,
+
+ CASE WHEN h.cancel_time IS NOT NULL THEN 6
+ WHEN h.frozen AND h.capture_time IS NULL THEN 7
+ WHEN h.current_shelf_lib IS NOT NULL AND h.current_shelf_lib <> h.pickup_lib THEN 8
+ WHEN h.fulfillment_time IS NOT NULL THEN 9
+ WHEN h.current_copy IS NULL THEN 1
+ WHEN h.capture_time IS NULL THEN 2
+ WHEN cp.status = 6 THEN 3
+ WHEN EXTRACT(EPOCH FROM COALESCE(NULLIF(BTRIM(hold_wait_time.value,'"'),''),'0 seconds')::INTERVAL) = 0 THEN 4
+ WHEN NOW() + COALESCE(NULLIF(BTRIM(hold_wait_time.value,'"'),''),'0 seconds')::INTERVAL > NOW() THEN 5
+ ELSE 5
+ END AS hold_status,
+
+ (h.cancel_time IS NOT NULL OR (h.current_shelf_lib IS NOT NULL AND h.current_shelf_lib <> h.pickup_lib)) AS clear_me,
+
+ (h.usr <> h.requestor) AS is_staff_hold,
+
+ cc.id AS cc_id, cc.label AS cc_label,
+
+ pl.id AS pl_id, pl.parent_ou AS pl_parent_ou, pl.ou_type AS pl_ou_type,
+ pl.ill_address AS pl_ill_address, pl.holds_address AS pl_holds_address,
+ pl.mailing_address AS pl_mailing_address, pl.billing_address AS pl_billing_address,
+ pl.shortname AS pl_shortname, pl.name AS pl_name, pl.email AS pl_email,
+ pl.phone AS pl_phone, pl.opac_visible AS pl_opac_visible, pl.fiscal_calendar AS pl_fiscal_calendar,
+
+ tr.id AS tr_id, tr.source_send_time AS tr_source_send_time, tr.dest_recv_time AS tr_dest_recv_time,
+ tr.target_copy AS tr_target_copy, tr.source AS tr_source, tr.dest AS tr_dest, tr.prev_hop AS tr_prev_hop,
+ tr.copy_status AS tr_copy_status, tr.persistant_transfer AS tr_persistant_transfer,
+ tr.prev_dest AS tr_prev_dest, tr.hold AS tr_hold, tr.cancel_time AS tr_cancel_time,
+
+ notes.count AS note_count,
+
+ u.id AS usr_id, u.card AS usr_card, u.profile AS usr_profile, u.usrname AS usr_usrname,
+ u.email AS usr_email, u.standing AS usr_standing, u.ident_type AS usr_ident_type,
+ u.ident_value AS usr_ident_value, u.ident_type2 AS usr_ident_type2,
+ u.ident_value2 AS usr_ident_value2, u.net_access_level AS usr_net_access_level,
+ u.photo_url AS usr_photo_url, u.prefix AS usr_prefix, u.first_given_name AS usr_first_given_name,
+ u.second_given_name AS usr_second_given_name, u.family_name AS usr_family_name,
+ u.suffix AS usr_suffix, u.alias AS usr_alias, u.day_phone AS usr_day_phone,
+ u.evening_phone AS usr_evening_phone, u.other_phone AS usr_other_phone,
+ u.mailing_address AS usr_mailing_address, u.billing_address AS usr_billing_address,
+ u.home_ou AS usr_home_ou, u.dob AS usr_dob, u.active AS usr_active,
+ u.master_account AS usr_master_account, u.super_user AS usr_super_user,
+ u.barred AS usr_barred, u.deleted AS usr_deleted, u.juvenile AS usr_juvenile,
+ u.usrgroup AS usr_usrgroup, u.claims_returned_count AS usr_claims_returned_count,
+ u.credit_forward_balance AS usr_credit_forward_balance, u.last_xact_id AS usr_last_xact_id,
+ u.alert_message AS usr_alert_message, u.create_date AS usr_create_date,
+ u.expire_date AS usr_expire_date, u.claims_never_checked_out_count AS usr_claims_never_checked_out_count,
+ u.last_update_time AS usr_last_update_time,
+
+ CASE WHEN u.alias IS NOT NULL THEN
+ u.alias
+ ELSE
+ u.first_given_name
+ END AS usr_alias_or_first_given_name,
+
+ CASE WHEN u.alias IS NOT NULL THEN
+ u.alias
+ ELSE
+ REGEXP_REPLACE(ARRAY_TO_STRING(ARRAY[
+ COALESCE(u.family_name, ''),
+ COALESCE(u.suffix, ''),
+ ', ',
+ COALESCE(u.prefix, ''),
+ COALESCE(u.first_given_name, ''),
+ COALESCE(u.second_given_name, '')
+ ], ' '), E'\\s+,', ',')
+ END AS usr_alias_or_display_name,
+
+ REGEXP_REPLACE(ARRAY_TO_STRING(ARRAY[
+ COALESCE(u.family_name, ''),
+ COALESCE(u.suffix, ''),
+ ', ',
+ COALESCE(u.prefix, ''),
+ COALESCE(u.first_given_name, ''),
+ COALESCE(u.second_given_name, '')
+ ], ' '), E'\\s+,', ',') AS usr_display_name,
+
+ uc.id AS ucard_id, uc.barcode AS ucard_barcode, uc.usr AS ucard_usr, uc.active AS ucard_active,
+
+ ru.id AS rusr_id, ru.card AS rusr_card, ru.profile AS rusr_profile, ru.usrname AS rusr_usrname,
+ ru.email AS rusr_email, ru.standing AS rusr_standing, ru.ident_type AS rusr_ident_type,
+ ru.ident_value AS rusr_ident_value, ru.ident_type2 AS rusr_ident_type2,
+ ru.ident_value2 AS rusr_ident_value2, ru.net_access_level AS rusr_net_access_level,
+ ru.photo_url AS rusr_photo_url, ru.prefix AS rusr_prefix, ru.first_given_name AS rusr_first_given_name,
+ ru.second_given_name AS rusr_second_given_name, ru.family_name AS rusr_family_name,
+ ru.suffix AS rusr_suffix, ru.alias AS rusr_alias, ru.day_phone AS rusr_day_phone,
+ ru.evening_phone AS rusr_evening_phone, ru.other_phone AS rusr_other_phone,
+ ru.mailing_address AS rusr_mailing_address, ru.billing_address AS rusr_billing_address,
+ ru.home_ou AS rusr_home_ou, ru.dob AS rusr_dob, ru.active AS rusr_active,
+ ru.master_account AS rusr_master_account, ru.super_user AS rusr_super_user,
+ ru.barred AS rusr_barred, ru.deleted AS rusr_deleted, ru.juvenile AS rusr_juvenile,
+ ru.usrgroup AS rusr_usrgroup, ru.claims_returned_count AS rusr_claims_returned_count,
+ ru.credit_forward_balance AS rusr_credit_forward_balance, ru.last_xact_id AS rusr_last_xact_id,
+ ru.alert_message AS rusr_alert_message, ru.create_date AS rusr_create_date,
+ ru.expire_date AS rusr_expire_date, ru.claims_never_checked_out_count AS rusr_claims_never_checked_out_count,
+ ru.last_update_time AS rusr_last_update_time,
+
+ ruc.id AS rucard_id, ruc.barcode AS rucard_barcode, ruc.usr AS rucard_usr, ruc.active AS rucard_active,
+
+ cp.id AS cp_id, cp.circ_lib AS cp_circ_lib, cp.creator AS cp_creator, cp.call_number AS cp_call_number,
+ cp.editor AS cp_editor, cp.create_date AS cp_create_date, cp.edit_date AS cp_edit_date,
+ cp.copy_number AS cp_copy_number, cp.status AS cp_status, cp.location AS cp_location,
+ cp.loan_duration AS cp_loan_duration, cp.fine_level AS cp_fine_level, cp.age_protect AS cp_age_protect,
+ cp.circulate AS cp_circulate, cp.deposit AS cp_deposit, cp.ref AS cp_ref, cp.holdable AS cp_holdable,
+ cp.deposit_amount AS cp_deposit_amount, cp.price AS cp_price, cp.barcode AS cp_barcode,
+ cp.circ_modifier AS cp_circ_modifier, cp.circ_as_type AS cp_circ_as_type, cp.dummy_title AS cp_dummy_title,
+ cp.dummy_author AS cp_dummy_author, cp.alert_message AS cp_alert_message, cp.opac_visible AS cp_opac_visible,
+ cp.deleted AS cp_deleted, cp.floating AS cp_floating, cp.dummy_isbn AS cp_dummy_isbn,
+ cp.status_changed_time AS cp_status_change_time, cp.active_date AS cp_active_date,
+ cp.mint_condition AS cp_mint_condition, cp.cost AS cp_cost,
+
+ cs.id AS cs_id, cs.name AS cs_name, cs.holdable AS cs_holdable, cs.opac_visible AS cs_opac_visible,
+ cs.copy_active AS cs_copy_active, cs.restrict_copy_delete AS cs_restrict_copy_delete,
+ cs.is_available AS cs_is_available,
+
+ siss.label AS issuance_label,
+
+ cn.id AS cn_id, cn.creator AS cn_creator, cn.create_date AS cn_create_date, cn.editor AS cn_editor,
+ cn.edit_date AS cn_edit_date, cn.record AS cn_record, cn.owning_lib AS cn_owning_lib, cn.label AS cn_label,
+ cn.deleted AS cn_deleted, cn.prefix AS cn_prefix, cn.suffix AS cn_suffix, cn.label_class AS cn_label_class,
+ cn.label_sortkey AS cn_label_sortkey,
+
+ p.id AS p_id, p.record AS p_record, p.label AS p_label, p.label_sortkey AS p_label_sortkey, p.deleted AS p_deleted,
+
+ acnp.label AS ancp_label, acns.label AS ancs_label,
+ TRIM(acnp.label || ' ' || cn.label || ' ' || acns.label) AS cn_full_label,
+
+ r.bib_record AS record_id,
+
+ t.value AS title,
+ a.value AS author,
+
+ acpl.id AS acpl_id, acpl.name AS acpl_name, acpl.owning_lib AS acpl_owning_lib, acpl.holdable AS acpl_holdable,
+ acpl.hold_verify AS acpl_hold_verify, acpl.opac_visible AS acpl_opac_visible, acpl.circulate AS acpl_circulate,
+ acpl.label_prefix AS acpl_label_prefix, acpl.label_suffix AS acpl_label_suffix,
+ acpl.checkin_alert AS acpl_checkin_alert, acpl.deleted AS acpl_deleted, acpl.url AS acpl_url,
+
+ COALESCE(acplo.position, acpl_ordered.fallback_position) AS copy_location_order_position,
+
+ ROW_NUMBER() OVER (
+ PARTITION BY r.bib_record
+ ORDER BY h.cut_in_line DESC NULLS LAST, h.request_time DESC
+ ) AS relative_queue_position,
+
+ EXTRACT(EPOCH FROM COALESCE(
+ NULLIF(BTRIM(default_estimated_wait_interval.value,'"'),''),
+ '0 seconds'
+ )::INTERVAL) AS default_estimated_wait,
+
+ EXTRACT(EPOCH FROM COALESCE(
+ NULLIF(BTRIM(min_estimated_wait_interval.value,'"'),''),
+ '0 seconds'
+ )::INTERVAL) AS min_estimated_wait,
+
+ COALESCE(hold_wait.potenials,0) AS potentials,
+ COALESCE(hold_wait.other_holds,0) AS other_holds,
+ COALESCE(hold_wait.total_wait_time,0) AS total_wait_time,
+
+ n.count AS notification_count,
+ n.max AS last_notification_time
+
+ FROM action.hold_request h
+ JOIN reporter.hold_request_record r ON (r.id = h.id)
+ JOIN actor.usr u ON (u.id = h.usr)
+ JOIN actor.card uc ON (uc.id = u.card)
+ JOIN actor.usr ru ON (ru.id = h.requestor)
+ JOIN actor.card ruc ON (ruc.id = ru.card)
+ JOIN actor.org_unit pl ON (h.pickup_lib = pl.id)
+ JOIN t_field ON TRUE
+ JOIN a_field ON TRUE
+ LEFT JOIN action.hold_request_cancel_cause cc ON (h.cancel_cause = cc.id)
+ LEFT JOIN biblio.monograph_part p ON (h.hold_type = 'P' AND p.id = h.target)
+ LEFT JOIN serial.issuance siss ON (h.hold_type = 'I' AND siss.id = h.target)
+ LEFT JOIN asset.copy cp ON (h.current_copy = cp.id OR (h.hold_type IN ('C','F','R') AND cp.id = h.target))
+ LEFT JOIN config.copy_status cs ON (cp.status = cs.id)
+ LEFT JOIN asset.copy_location acpl ON (cp.location = acpl.id)
+ LEFT JOIN asset.copy_location_order acplo ON (cp.location = acplo.location AND cp.circ_lib = acplo.org)
+ LEFT JOIN (
+ SELECT *, (ROW_NUMBER() OVER (ORDER BY name) + 1000000) AS fallback_position
+ FROM asset.copy_location
+ ) acpl_ordered ON (acpl_ordered.id = cp.location)
+ LEFT JOIN asset.call_number cn ON (cn.id = cp.call_number OR (h.hold_type = 'V' AND cn.id = h.target))
+ LEFT JOIN asset.call_number_prefix acnp ON (cn.prefix = acnp.id)
+ LEFT JOIN asset.call_number_suffix acns ON (cn.suffix = acns.id)
+ LEFT JOIN LATERAL (SELECT * FROM action.hold_transit_copy WHERE h.id = hold ORDER BY id DESC LIMIT 1) tr ON TRUE
+ LEFT JOIN LATERAL (SELECT COUNT(*) FROM action.hold_request_note WHERE h.id = hold AND (pub = TRUE OR staff = $is_staff_request)) notes ON TRUE
+ LEFT JOIN LATERAL (SELECT COUNT(*), MAX(notify_time) FROM action.hold_notification WHERE h.id = hold) n ON TRUE
+ LEFT JOIN LATERAL (SELECT FIRST(value) AS value FROM metabib.display_entry WHERE source = r.bib_record AND field = t_field.field) t ON TRUE
+ LEFT JOIN LATERAL (SELECT FIRST(value) AS value FROM metabib.display_entry WHERE source = r.bib_record AND field = a_field.field) a ON TRUE
+ LEFT JOIN LATERAL actor.org_unit_ancestor_setting('circ.holds.default_estimated_wait_interval',u.home_ou) AS default_estimated_wait_interval ON TRUE
+ LEFT JOIN LATERAL actor.org_unit_ancestor_setting('circ.holds.min_estimated_wait_interval',u.home_ou) AS min_estimated_wait_interval ON TRUE
+ LEFT JOIN LATERAL actor.org_unit_ancestor_setting('circ.hold_shelf_status_delay',h.pickup_lib) AS hold_wait_time ON TRUE,
+ LATERAL (
+ SELECT COUNT(*) AS potenials,
+ COUNT(DISTINCT hold) AS other_holds,
+ SUM(
+ EXTRACT(EPOCH FROM
+ COALESCE(
+ cm.avg_wait_time,
+ COALESCE(NULLIF(BTRIM(default_estimated_wait_interval.value,'"'),''),'0 seconds')::INTERVAL
+ )
+ )
+ ) AS total_wait_time
+ FROM action.hold_copy_map m
+ JOIN asset.copy cp ON (cp.id = m.target_copy)
+ LEFT JOIN config.circ_modifier cm ON (cp.circ_modifier = cm.code)
+ WHERE m.hold = h.id
+ ) AS hold_wait
+ WHERE TRUE
+ SQL
+
+ my %field_map = (
+ record_id => 'r.bib_record',
+ usr_id => 'u.id',
+ cs_id => 'cs.id',
+ cp_id => 'cp.id',
+ cancel_time => 'h.cancel_time',
+ tr_cancel_time => 'tr.cancel_time',
+ );
+
+ my $restricted = 0;
+ for my $r (keys %$restrictions) {
+ my $real = $field_map{$r} || $r;
+ next if ($r =~ /[^a-z_.]/); # skip obvious bad inputs
+
+ my $not = '';
+ if (ref($$restrictions{$r}) and ref($$restrictions{$r}) =~ /HASH/) {
+ $not = 'NOT';
+ $$restrictions{$r} = $$restrictions{$r}{not};
+ }
+
+ if (!defined($$restrictions{$r})) {
+ $select .= " AND $real IS $not NULL ";
+ } elsif (ref($$restrictions{$r})) {
+ $select .= " AND $real $not IN (\$_$$\$" . join("\$_$$\$,\$_$$\$", @{$$restrictions{$r}}) . "\$_$$\$)";
+ } else {
+ $not = '!' if $not;
+ $select .= " AND $real $not= \$_$$\$$$restrictions{$r}\$_$$\$";
+ }
+
+ $restricted++;
+ }
+
+ return 0 unless $restricted;
+
+ my @ob;
+ for my $o (@$order_by) {
+ next unless $o;
+ my ($r) = keys %$o;
+ next if ($r =~ /[^a-z_.]/); # skip obvious bad inputs
+ my $real = $field_map{$r} || $r;
+ push(@ob, $real);
+ $ob[-1] .= ' DESC' if ($$o{$r}->{dir} and $$o{$r}->{dir} =~ /^d/i);
+ $ob[-1] .= ' NULLS LAST' if ($$o{$r}->{nulls} and $$o{$r}->{nulls} =~ /^l/i);
+ $ob[-1] .= ' NULLS FIRST' if ($$o{$r}->{nulls} and $$o{$r}->{nulls} =~ /^f/i);
+ }
+
+ $select .= ' ORDER BY ' . join(', ', @ob) if (@ob);
+ $select .= ' LIMIT ' . $limit if ($limit and $limit =~ /^\d+$/);
+ $select .= ' OFFSET ' . $offset if ($offset and $offset =~ /^\d+$/);
+
+ my $sth = action::hold_request->db_Main->prepare($select);
+ $sth->execute();
+
+ my @list = $sth->fetchall_hash;
+ $client->respond(scalar(@list)); # send the row count first, for progress tracking
+ $client->respond( $_ ) for (@list);
+
+ $client->respond_complete;
+}
+__PACKAGE__->register_method(
+ api_name => 'open-ils.storage.action.live_holds.wide_hash',
+ api_level => 1,
+ stream => 1,
+ max_bundle_count=> 1,
+ method => 'wide_hold_data',
+);
+
+
1;
+
<eg-grid
id-field="id"
- features="-sort,-multisort"
+ features="clientsort,"
items-provider="hold_grid_data_provider"
grid-controls="hold_grid_controls"
- persist-key="cat.catalog.holds"
+ persist-key="cat.catalog.wide_holds"
dateformat="{{$root.egDateAndTimeFormat}}">
<eg-grid-menu-item handler="detail_view"
<eg-grid-menu-item handler="transfer_holds_to_marked"
label="[% l('Transfer All Title Holds') %]"></eg-grid-menu-item> -->
- <eg-grid-action handler="grid_actions.show_recent_circs" group="[% l('Copy') %]"
+ <eg-grid-action handler="grid_actions.show_recent_circs_wide" group="[% l('Copy') %]"
label="[% l('Show Last Few Circulations') %]"></eg-grid-action>
- <eg-grid-action handler="grid_actions.show_patrons" group="[% l('Patron') %]"
+ <eg-grid-action handler="grid_actions.show_patrons_wide" group="[% l('Patron') %]"
label="[% l('Retrieve Patron') %]"></eg-grid-action>
- <eg-grid-action group="[% l('Hold') %]" handler="grid_actions.set_copy_quality"
+ <eg-grid-action group="[% l('Hold') %]" handler="grid_actions.set_copy_quality_wide"
label="[% l('Set Desired Copy Quality') %]"></eg-grid-action>
- <eg-grid-action group="[% l('Hold') %]" handler="grid_actions.edit_pickup_lib"
+ <eg-grid-action group="[% l('Hold') %]" handler="grid_actions.edit_pickup_lib_wide"
label="[% l('Edit Pickup Library') %]"></eg-grid-action>
- <eg-grid-action group="[% l('Hold') %]" handler="grid_actions.edit_notify_prefs"
+ <eg-grid-action group="[% l('Hold') %]" handler="grid_actions.edit_notify_prefs_wide"
label="[% l('Edit Notification Settings') %]"></eg-grid-action>
- <eg-grid-action group="[% l('Hold') %]" handler="grid_actions.edit_dates"
+ <eg-grid-action group="[% l('Hold') %]" handler="grid_actions.edit_dates_wide"
label="[% l('Edit Hold Dates') %]"></eg-grid-action>
- <eg-grid-action handler="grid_actions.activate" group="[% l('Hold') %]"
+ <eg-grid-action handler="grid_actions.activate_wide" group="[% l('Hold') %]"
label="[% l('Activate') %]"></eg-grid-action>
- <eg-grid-action handler="grid_actions.suspend" group="[% l('Hold') %]"
+ <eg-grid-action handler="grid_actions.suspend_wide" group="[% l('Hold') %]"
label="[% l('Suspend') %]"></eg-grid-action>
- <eg-grid-action handler="grid_actions.set_top_of_queue" group="[% l('Hold') %]"
+ <eg-grid-action handler="grid_actions.set_top_of_queue_wide" group="[% l('Hold') %]"
label="[% l('Set Top of Queue') %]"></eg-grid-action>
- <eg-grid-action handler="grid_actions.clear_top_of_queue" group="[% l('Hold') %]"
+ <eg-grid-action handler="grid_actions.clear_top_of_queue_wide" group="[% l('Hold') %]"
label="[% l('Un-Set Top of Queue') %]"></eg-grid-action>
- <eg-grid-action handler="grid_actions.transfer_to_marked_title" group="[% l('Hold') %]"
+ <eg-grid-action handler="grid_actions.transfer_to_marked_title_wide" group="[% l('Hold') %]"
label="[% l('Transfer To Marked Title') %]"></eg-grid-action>
- <eg-grid-action handler="grid_actions.mark_damaged" group="[% l('Copy') %]"
+ <eg-grid-action handler="grid_actions.mark_damaged_wide" group="[% l('Copy') %]"
label="[% l('Mark Item Damaged') %]"></eg-grid-action>
- <eg-grid-action handler="grid_actions.mark_missing" group="[% l('Copy') %]"
+ <eg-grid-action handler="grid_actions.mark_missing_wide" group="[% l('Copy') %]"
label="[% l('Mark Item Missing') %]"></eg-grid-action>
- <eg-grid-action handler="grid_actions.retarget" group="[% l('Hold') %]"
+ <eg-grid-action handler="grid_actions.retarget_wide" group="[% l('Hold') %]"
label="[% l('Find Another Target') %]"></eg-grid-action>
- <eg-grid-action handler="grid_actions.cancel_hold" group="[% l('Hold') %]"
+ <eg-grid-action handler="grid_actions.cancel_hold_wide" group="[% l('Hold') %]"
label="[% l('Cancel Hold') %]"></eg-grid-action>
<eg-grid-field label="[% l('Hold ID') %]" path='hold.id'></eg-grid-field>
<eg-grid-field label="[% l('Current Copy') %]"
- path='hold.current_copy.barcode'>
- <a href="./cat/item/{{item.hold.current_copy().id()}}/summary" target="_self">
- {{item.hold.current_copy().barcode()}}
+ path='hold.cp_barcode'>
+ <a href="./cat/item/{{item.hold.cp_id}}/summary" target="_self">
+ {{item.hold.cp_barcode}}
</a>
</eg-grid-field>
- <eg-grid-field label="[% l('Patron Barcode') %]">{{item.patron_barcode}}</eg-grid-field>
- <eg-grid-field label="[% l('Patron alias') %]">{{item.patron_alias}}</eg-grid-field>
+ <eg-grid-field label="[% l('Patron Barcode') %]" path='hold.ucard_barcode' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Patron alias') %]">{{item.usr_alias}}</eg-grid-field>
<eg-grid-field label="[% l('Request Date') %]" path='hold.request_time' datatype="timestamp"></eg-grid-field>
<eg-grid-field label="[% l('Capture Date') %]" path='hold.capture_time' datatype="timestamp"></eg-grid-field>
<eg-grid-field label="[% l('Available Date') %]" path='hold.shelf_time' datatype="timestamp"></eg-grid-field>
<eg-grid-field label="[% l('Hold Type') %]" path='hold.hold_type'></eg-grid-field>
- <eg-grid-field label="[% l('Pickup Library') %]" path='hold.pickup_lib.shortname'></eg-grid-field>
+ <eg-grid-field label="[% l('Pickup Library') %]" path='hold.pl_shortname'></eg-grid-field>
- <eg-grid-field label="[% l('Title') %]" path='mvr.title'>
- <a target="_self" href="[% ctx.base_path %]/staff/cat/catalog/record/{{item.mvr.doc_id()}}">
- {{item.mvr.title()}}
- </a>
- </eg-grid-field>
+ <eg-grid-field label="[% l('Title') %]" path='hold.title'>
+ <a target="_self" href="[% ctx.base_path %]/staff/cat/catalog/record/{{item.hold.record_id}}">
+ {{item.hold.title}}
+ </a>
+ </eg-grid-field>
- <eg-grid-field label="[% l('Author') %]" path='mvr.author'></eg-grid-field>
- <eg-grid-field label="[% l('Potential Copies') %]" path='potential_copies'></eg-grid-field>
- <eg-grid-field label="[% l('Status') %]" path='status_string'></eg-grid-field>
+ <eg-grid-field label="[% l('Author') %]" path='hold.author'></eg-grid-field>
+ <eg-grid-field label="[% l('Potential Copies') %]" path='hold.potentials'></eg-grid-field>
+ <eg-grid-field label="[% l('Status') %]" path='status_string'></eg-grid-field>
- <eg-grid-field label="[% l('Queue Position') %]" path='queue_position' hidden></eg-grid-field>
- <eg-grid-field path='hold.*' parent-idl-class="ahr" hidden></eg-grid-field>
- <eg-grid-field path='copy.*' parent-idl-class="acp" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Queue Position') %]" path='hold.relative_queue_position' hidden></eg-grid-field>
- <eg-grid-field path='hold.usr.id' parent-idl-class="ahr" label="[% l('User ID') %]" hidden></eg-grid-field>
- <eg-grid-field path='hold.usr.usrname' parent-idl-class="ahr" label="[% l('Username') %]" hidden></eg-grid-field>
- <eg-grid-field path='hold.usr.first_given_name' parent-idl-class="ahr" label="[% l('First Name') %]" hidden></eg-grid-field>
- <eg-grid-field path='hold.usr.family_name' parent-idl-class="ahr" label="[% l('Last Name') %]" hidden></eg-grid-field>
- <eg-grid-field path='hold.requestor.id' parent-idl-class="ahr" label="[% l('Requestor ID') %]" hidden></eg-grid-field>
- <eg-grid-field path='hold.requestor.usrname' parent-idl-class="ahr" label="[% l('Requestor Username') %]" hidden></eg-grid-field>
+ <eg-grid-field path='hold.usr_id' label="[% l('User ID') %]" hidden></eg-grid-field>
+ <eg-grid-field path='hold.usr_usrname' label="[% l('Username') %]" hidden></eg-grid-field>
+ <eg-grid-field path='hold.usr_first_given_name' label="[% l('First Name') %]" hidden></eg-grid-field>
+ <eg-grid-field path='hold.usr_family_name' label="[% l('Last Name') %]" hidden></eg-grid-field>
+ <eg-grid-field path='hold.rusr_id' label="[% l('Requestor ID') %]" hidden></eg-grid-field>
+ <eg-grid-field path='hold.rusr_usrname' label="[% l('Requestor Username') %]" hidden></eg-grid-field>
- <eg-grid-field label="[% l('Copy Status') %]" path="hold.current_copy.status.name" hidden>
- </eg-grid-field>
+ <eg-grid-field label="[% l('Copy Status') %]" path="hold.cs_name" hidden></eg-grid-field>
- <eg-grid-field path='volume.*' parent-idl-class="acn" hidden></eg-grid-field>
- <eg-grid-field path='volume.prefix.label' label="[% l('CN Prefix') %]" parent-idl-class="acn" hidden></eg-grid-field>
- <eg-grid-field path='volume.suffix.label' label="[% l('CN Suffix') %]" parent-idl-class="acn" hidden></eg-grid-field>
+ <eg-grid-field path='hold.acnp_label' label="[% l('CN Prefix') %]" hidden></eg-grid-field>
+ <eg-grid-field path='hold.acns_label' label="[% l('CN Suffix') %]" hidden></eg-grid-field>
<eg-grid-field path='mvr.*' parent-idl-class="mvr" hidden></eg-grid-field>
+
+ <eg-grid-field label="[% l('Copy Status') %]" path="hold.cs_name" hidden></eg-grid-field>
+
+ <eg-grid-field label="[% l('Fulfillment Date/Time') %]" path='hold.fulfillment_time' datatype="timestamp" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Checkin Time') %]" path='hold.checkin_time' datatype="timestamp" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Return Time') %]" path='hold.return_time' datatype="timestamp" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Last Targeting Date/Time') %]" path='hold.prev_check_time' datatype="timestamp" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Expire Time') %]" path='hold.expire_time' datatype="timestamp" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Hold Cancel Date/Time') %]" path='hold.cancel_time' datatype="timestamp" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Cancelation note') %]" path='hold.cancel_note' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Hold Target') %]" path='hold.target' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Current Copy') %]" path='hold.current_copy' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Fulfilling Staff') %]" path='hold.fulfillment_staff' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Fulfilling Library') %]" path='hold.fulfillment_lib' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Requesting Library') %]" path='hold.request_lib' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Requesting User') %]" path='hold.requestor' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('User') %]" path='hold.usr' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Selection Library') %]" path='hold.selection_ou' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Item Selection Depth') %]" path='hold.selection_depth' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Holdable Formats (for M-type hold)') %]" path='hold.holdable_formats' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Notifications Phone Number') %]" path='hold.phone_notify' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Notifications SMS Number') %]" path='hold.sms_notify' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Notify by Email?') %]" path='hold.email_notify' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('SMS Carrier') %]" path='hold.sms_carrier' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Currently Frozen') %]" path='hold.frozen' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Activation Date') %]" path='hold.thaw_date' datatype="timestamp" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Top of Queue') %]" path='hold.cut_in_line' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Is Mint Condition') %]" path='hold.mint_condition' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Shelf Expire Time') %]" path='hold.shelf_expire_time' datatype="timestamp" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Current Shelf Library') %]" path='hold.current_shelf_lib' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Behind Desk') %]" path='hold.behind_desk' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Status') %]" path='hold.hold_status' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Clearable') %]" path='hold.clear_me' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Is Staff-placed Hold') %]" path='hold.is_staff_hold' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Cancelation Cause ID') %]" path='hold.cc_id' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Cancelation Cause') %]" path='hold.cc_label' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Pickup Library') %]" path='hold.pl_shortname'></eg-grid-field>
+ <eg-grid-field label="[% l('Pickup Library Name') %]" path='hold.pl_name' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Pickup Library Email') %]" path='hold.pl_email' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Pickup Library Phone') %]" path='hold.pl_phone' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Pickup Library Opac Visible') %]" path='hold.pl_opac_visible' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Transit ID') %]" path='hold.tr_id' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Transit Send Time') %]" path='hold.tr_source_send_time' datatype="timestamp" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Transit Receive Time') %]" path='hold.tr_dest_recv_time' datatype="timestamp" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Transit Copy') %]" path='hold.tr_target_copy' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Transit Source') %]" path='hold.tr_source' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Transit Destination') %]" path='hold.tr_dest' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Transit Copy Status') %]" path='hold.tr_copy_status' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Transit Hold') %]" path='hold.tr_hold' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Transit Cancel Time') %]" path='hold.tr_cancel_time' datatype="timestamp" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Hold Note Count') %]" path='hold.note_count' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('User Display Name') %]" path='hold.usr_display_name' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Requestor Username') %]" path='hold.rusr_usrname' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy ID') %]" path='hold.cp_id' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Number on Volume') %]" path='hold.cp_copy_number' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Fine Level') %]" path='hold.cp_fine_level' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Can Circulate') %]" path='hold.cp_circulate' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Deposit Amount') %]" path='hold.cp_deposit_amount' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Is Deposit Required') %]" path='hold.cp_deposit' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Is Reference') %]" path='hold.cp_ref' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Is Holdable') %]" path='hold.cp_holdable' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Price') %]" path='hold.cp_price' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Barcode') %]" path='hold.cp_barcode' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Circulation Modifier') %]" path='hold.cp_circ_modifier' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Circulate as MARC Type') %]" path='hold.cp_circ_as_type' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Precat Dummy Title') %]" path='hold.cp_dummy_title' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Precat Dummy Author') %]" path='hold.cp_dummy_author' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Alert Message (deprecated)') %]" path='hold.cp_alert_message' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy OPAC Visible') %]" path='hold.cp_opac_visible' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Deleted') %]" path='hold.cp_deleted' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Floating Group') %]" path='hold.cp_floating' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Precat Dummy ISBN') %]" path='hold.cp_dummy_isbn' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Status Change Time') %]" path='hold.cp_status_change_time' datatype="timestamp" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Active Date') %]" path='hold.cp_active_date' datatype="timestamp" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Is Mint Condition') %]" path='hold.cp_mint_condition' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Cost') %]" path='hold.cp_cost' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Status') %]" path='hold.cs_name' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Status Is Holdable') %]" path='hold.cs_holdable' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Status Is OPAC Visible') %]" path='hold.cs_opac_visible' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Status Is Copy-Active') %]" path='hold.cs_copy_active' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Status Is Deleted') %]" path='hold.cs_restrict_copy_delete' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Status Is Available') %]" path='hold.cs_is_available' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Issuance Label') %]" path='hold.issuance_label' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Call Number ID') %]" path='hold.cn_id' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('CN Label') %]" path='hold.cn_label' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('CN Label Class') %]" path='hold.cn_label_class' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('CN Sort Key') %]" path='hold.cn_label_sortkey' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Part ID') %]" path='hold.p_id' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Part Label') %]" path='hold.p_label' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Part Sort Key') %]" path='hold.p_label_sortkey' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Part Is Deleted') %]" path='hold.p_deleted' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('CN Full Label') %]" path='hold.cn_full_label' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Record ID') %]" path='hold.record_id' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Location ID') %]" path='hold.acpl_id' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Location') %]" path='hold.acpl_name' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Location Holdable') %]" path='hold.acpl_holdable' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Location Hold-Verify') %]" path='hold.acpl_hold_verify' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Location OPAC Visible') %]" path='hold.acpl_opac_visible' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Location Can Circulate') %]" path='hold.acpl_circulate' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Location Prefix') %]" path='hold.acpl_label_prefix' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Location Suffix') %]" path='hold.acpl_label_suffix' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Location Checkin Alert') %]" path='hold.acpl_checkin_alert' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Location Is Deleted') %]" path='hold.acpl_deleted' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Location URL') %]" path='hold.acpl_url' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Location Order') %]" path='hold.copy_location_order_position' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Default Estimated Wait Time') %]" path='hold.default_estimated_wait' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Minimum Estimated Wait Time') %]" path='hold.min_estimated_wait' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Peer Hold Count') %]" path='hold.other_holds' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Total Wait Time') %]" path='hold.total_wait_time' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Notify Count') %]" path='hold.notification_count' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Last Notify Time') %]" path='hold.last_notification_time' datatype="timestamp" hidden></eg-grid-field>
+
+
</eg-grid>
<div class="flex-row pad-vert">
-<div ng-if="print_list_progress !== null" class="strong-text-2">
- [% l('Loading... [_1]', '{{print_list_progress}}') %]
-</div>
-
<eg-grid
id-field="id"
- features="-sort,-multisort"
+ features="clientsort"
items-provider="gridDataProvider"
grid-controls="gridControls"
- persist-key="circ.holds.shelf"
+ persist-key="circ.wide_holds.shelf"
dateformat="{{$root.egDateAndTimeFormat}}">
<eg-grid-menu-item handler="detail_view"
label="[% l('Clear These Holds') %]"></eg-grid-menu-item>
<eg-grid-menu-item handler="print_shelf_list"
- label="[% l('Print Full List') %]"></eg-grid-menu-item>
+ label="[% l('Print Full List') %]"></eg-grid-menu-item>
- <eg-grid-action handler="grid_actions.show_recent_circs"
+ <eg-grid-action handler="grid_actions.show_recent_circs_wide"
label="[% l('Show Last Few Circulations') %]"></eg-grid-action>
- <eg-grid-action handler="grid_actions.show_patrons"
+ <eg-grid-action handler="grid_actions.show_patrons_wide"
label="[% l('Retrieve Patron') %]"></eg-grid-action>
<eg-grid-action divider="true"></eg-grid-action>
- <eg-grid-action handler="grid_actions.set_copy_quality"
+ <eg-grid-action handler="grid_actions.set_copy_quality_wide"
label="[% l('Set Desired Copy Quality') %]"></eg-grid-action>
- <eg-grid-action handler="grid_actions.edit_pickup_lib"
+ <eg-grid-action handler="grid_actions.edit_pickup_lib_wide"
label="[% l('Edit Pickup Library') %]"></eg-grid-action>
- <eg-grid-action handler="grid_actions.edit_notify_prefs"
+ <eg-grid-action handler="grid_actions.edit_notify_prefs_wide"
label="[% l('Edit Notification Settings') %]"></eg-grid-action>
- <eg-grid-action handler="grid_actions.edit_dates"
+ <eg-grid-action handler="grid_actions.edit_dates_wide"
label="[% l('Edit Hold Dates') %]"></eg-grid-action>
- <eg-grid-action handler="grid_actions.activate"
+ <eg-grid-action handler="grid_actions.activate_wide"
label="[% l('Activate') %]"></eg-grid-action>
- <eg-grid-action handler="grid_actions.suspend"
+ <eg-grid-action handler="grid_actions.suspend_wide"
label="[% l('Suspend') %]"></eg-grid-action>
- <eg-grid-action handler="grid_actions.set_top_of_queue"
+ <eg-grid-action handler="grid_actions.set_top_of_queue_wide"
label="[% l('Set Top of Queue') %]"></eg-grid-action>
- <eg-grid-action handler="grid_actions.clear_top_of_queue"
+ <eg-grid-action handler="grid_actions.clear_top_of_queue_wide"
label="[% l('Un-Set Top of Queue') %]"></eg-grid-action>
- <eg-grid-action handler="grid_actions.transfer_to_marked_title"
+ <eg-grid-action handler="grid_actions.transfer_to_marked_tit_widele"
label="[% l('Transfer To Marked Title') %]"></eg-grid-action>
- <eg-grid-action handler="grid_actions.mark_damaged"
+ <eg-grid-action handler="grid_actions.mark_damaged_wide"
label="[% l('Mark Item Damaged') %]"></eg-grid-action>
- <eg-grid-action handler="grid_actions.mark_missing"
+ <eg-grid-action handler="grid_actions.mark_missing_wide"
label="[% l('Mark Item Missing') %]"></eg-grid-action>
<eg-grid-action divider="true"></eg-grid-action>
- <eg-grid-action handler="grid_actions.retarget"
+ <eg-grid-action handler="grid_actions.retarget_wide"
label="[% l('Find Another Target') %]"></eg-grid-action>
- <eg-grid-action handler="grid_actions.cancel_hold"
+ <eg-grid-action handler="grid_actions.cancel_hold_wide"
label="[% l('Cancel Hold') %]"></eg-grid-action>
- <eg-grid-action handler="grid_actions.uncancel_hold"
+ <eg-grid-action handler="grid_actions.uncancel_hold_wide"
label="[% l('Uncancel Hold') %]"></eg-grid-action>
<eg-grid-field label="[% l('Hold ID') %]" path='hold.id'></eg-grid-field>
<eg-grid-field label="[% l('Current Copy') %]"
- path='hold.current_copy.barcode'>
- <a href="./cat/item/{{item.hold.current_copy().id()}}/summary" target="_self">
- {{item.hold.current_copy().barcode()}}
+ path='hold.cp_barcode'>
+ <a href="./cat/item/{{item.hold.cp_id}}/summary" target="_self">
+ {{item.hold.cp_barcode}}
</a>
</eg-grid-field>
<eg-grid-field label="[% l('Capture Date') %]" path='hold.capture_time' datatype="timestamp"></eg-grid-field>
<eg-grid-field label="[% l('Available Date') %]" path='hold.shelf_time' datatype="timestamp"></eg-grid-field>
<eg-grid-field label="[% l('Hold Type') %]" path='hold.hold_type'></eg-grid-field>
- <eg-grid-field label="[% l('Pickup Library') %]" path='hold.pickup_lib.shortname'></eg-grid-field>
+ <eg-grid-field label="[% l('Pickup Library') %]" path='hold.pl_shortname'></eg-grid-field>
<eg-grid-field label="[% l('Post-Clear') %]" path='post_clear'></eg-grid-field>
- <eg-grid-field label="[% l('Title') %]" path='mvr.title'>
- <a target="_self" href="[% ctx.base_path %]/staff/cat/catalog/record/{{item.mvr.doc_id()}}">
- {{item.mvr.title()}}
+ <eg-grid-field label="[% l('Title') %]" path='hold.title'>
+ <a target="_self" href="[% ctx.base_path %]/staff/cat/catalog/record/{{item.hold.record_id}}">
+ {{item.hold.title}}
</a>
</eg-grid-field>
- <eg-grid-field label="[% l('Author') %]" path='mvr.author'></eg-grid-field>
- <eg-grid-field label="[% l('Potential Copies') %]" path='potential_copies'></eg-grid-field>
+ <eg-grid-field label="[% l('Author') %]" path='hold.author'></eg-grid-field>
+ <eg-grid-field label="[% l('Potential Copies') %]" path='hold.potentials'></eg-grid-field>
<eg-grid-field label="[% l('Status') %]" path='status_string'></eg-grid-field>
- <eg-grid-field label="[% l('Queue Position') %]" path='queue_position' hidden></eg-grid-field>
- <eg-grid-field path='hold.usr.*' parent-idl-class="ahr" hidden></eg-grid-field>
- <eg-grid-field path='hold.requestor.*' parent-idl-class="ahr" hidden></eg-grid-field>
- <eg-grid-field label="[% l('Copy Status') %]" path="hold.current_copy.status.name" hidden>
- </eg-grid-field>
- <eg-grid-field path='hold.*' parent-idl-class="ahr" hidden></eg-grid-field>
- <eg-grid-field path='copy.*' parent-idl-class="acp" hidden></eg-grid-field>
- <eg-grid-field path='volume.*' parent-idl-class="acn" hidden></eg-grid-field>
- <eg-grid-field path='volume.prefix.label' label="[% l('CN Prefix') %]" parent-idl-class="acn" hidden></eg-grid-field>
- <eg-grid-field path='volume.suffix.label' label="[% l('CN Suffix') %]" parent-idl-class="acn" hidden></eg-grid-field>
- <eg-grid-field path='mvr.*' parent-idl-class="mvr" hidden></eg-grid-field>
-</eg-grid>
+ <eg-grid-field label="[% l('Queue Position') %]" path='hold.relative_queue_position' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Status') %]" path="hold.cs_name" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Fulfillment Date/Time') %]" path='hold.fulfillment_time' datatype="timestamp" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Checkin Time') %]" path='hold.checkin_time' datatype="timestamp" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Return Time') %]" path='hold.return_time' datatype="timestamp" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Last Targeting Date/Time') %]" path='hold.prev_check_time' datatype="timestamp" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Expire Time') %]" path='hold.expire_time' datatype="timestamp" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Hold Cancel Date/Time') %]" path='hold.cancel_time' datatype="timestamp" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Cancelation note') %]" path='hold.cancel_note' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Hold Target') %]" path='hold.target' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Current Copy') %]" path='hold.current_copy' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Fulfilling Staff') %]" path='hold.fulfillment_staff' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Fulfilling Library') %]" path='hold.fulfillment_lib' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Requesting Library') %]" path='hold.request_lib' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Requesting User') %]" path='hold.requestor' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('User') %]" path='hold.usr' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Selection Library') %]" path='hold.selection_ou' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Item Selection Depth') %]" path='hold.selection_depth' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Holdable Formats (for M-type hold)') %]" path='hold.holdable_formats' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Notifications Phone Number') %]" path='hold.phone_notify' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Notifications SMS Number') %]" path='hold.sms_notify' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Notify by Email?') %]" path='hold.email_notify' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('SMS Carrier') %]" path='hold.sms_carrier' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Currently Frozen') %]" path='hold.frozen' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Activation Date') %]" path='hold.thaw_date' datatype="timestamp" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Top of Queue') %]" path='hold.cut_in_line' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Is Mint Condition') %]" path='hold.mint_condition' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Shelf Expire Time') %]" path='hold.shelf_expire_time' datatype="timestamp" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Current Shelf Library') %]" path='hold.current_shelf_lib' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Behind Desk') %]" path='hold.behind_desk' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Status') %]" path='hold.hold_status' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Clearable') %]" path='hold.clear_me' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Is Staff-placed Hold') %]" path='hold.is_staff_hold' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Cancelation Cause ID') %]" path='hold.cc_id' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Cancelation Cause') %]" path='hold.cc_label' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Pickup Library') %]" path='hold.pl_shortname'></eg-grid-field>
+ <eg-grid-field label="[% l('Pickup Library Name') %]" path='hold.pl_name' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Pickup Library Email') %]" path='hold.pl_email' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Pickup Library Phone') %]" path='hold.pl_phone' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Pickup Library Opac Visible') %]" path='hold.pl_opac_visible' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Transit ID') %]" path='hold.tr_id' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Transit Send Time') %]" path='hold.tr_source_send_time' datatype="timestamp" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Transit Receive Time') %]" path='hold.tr_dest_recv_time' datatype="timestamp" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Transit Copy') %]" path='hold.tr_target_copy' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Transit Source') %]" path='hold.tr_source' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Transit Destination') %]" path='hold.tr_dest' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Transit Copy Status') %]" path='hold.tr_copy_status' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Transit Hold') %]" path='hold.tr_hold' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Transit Cancel Time') %]" path='hold.tr_cancel_time' datatype="timestamp" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Hold Note Count') %]" path='hold.note_count' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('User Display Name') %]" path='hold.usr_display_name' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('User Barcode') %]" path='hold.ucard_barcode' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Requestor Username') %]" path='hold.rusr_usrname' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy ID') %]" path='hold.cp_id' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Number on Volume') %]" path='hold.cp_copy_number' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Fine Level') %]" path='hold.cp_fine_level' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Can Circulate') %]" path='hold.cp_circulate' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Deposit Amount') %]" path='hold.cp_deposit_amount' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Is Deposit Required') %]" path='hold.cp_deposit' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Is Reference') %]" path='hold.cp_ref' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Is Holdable') %]" path='hold.cp_holdable' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Price') %]" path='hold.cp_price' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Barcode') %]" path='hold.cp_barcode' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Circulation Modifier') %]" path='hold.cp_circ_modifier' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Circulate as MARC Type') %]" path='hold.cp_circ_as_type' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Precat Dummy Title') %]" path='hold.cp_dummy_title' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Precat Dummy Author') %]" path='hold.cp_dummy_author' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Alert Message (deprecated)') %]" path='hold.cp_alert_message' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy OPAC Visible') %]" path='hold.cp_opac_visible' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Deleted') %]" path='hold.cp_deleted' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Floating Group') %]" path='hold.cp_floating' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Precat Dummy ISBN') %]" path='hold.cp_dummy_isbn' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Status Change Time') %]" path='hold.cp_status_change_time' datatype="timestamp" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Active Date') %]" path='hold.cp_active_date' datatype="timestamp" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Is Mint Condition') %]" path='hold.cp_mint_condition' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Cost') %]" path='hold.cp_cost' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Status') %]" path='hold.cs_name' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Status Is Holdable') %]" path='hold.cs_holdable' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Status Is OPAC Visible') %]" path='hold.cs_opac_visible' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Status Is Copy-Active') %]" path='hold.cs_copy_active' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Status Is Deleted') %]" path='hold.cs_restrict_copy_delete' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Status Is Available') %]" path='hold.cs_is_available' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Issuance Label') %]" path='hold.issuance_label' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Call Number ID') %]" path='hold.cn_id' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('CN Label') %]" path='hold.cn_label' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('CN Label Class') %]" path='hold.cn_label_class' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('CN Sort Key') %]" path='hold.cn_label_sortkey' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Part ID') %]" path='hold.p_id' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Part Label') %]" path='hold.p_label' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Part Sort Key') %]" path='hold.p_label_sortkey' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Part Is Deleted') %]" path='hold.p_deleted' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('CN Full Label') %]" path='hold.cn_full_label' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Record ID') %]" path='hold.record_id' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Location ID') %]" path='hold.acpl_id' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Location') %]" path='hold.acpl_name' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Location Holdable') %]" path='hold.acpl_holdable' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Location Hold-Verify') %]" path='hold.acpl_hold_verify' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Location OPAC Visible') %]" path='hold.acpl_opac_visible' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Location Can Circulate') %]" path='hold.acpl_circulate' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Location Prefix') %]" path='hold.acpl_label_prefix' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Location Suffix') %]" path='hold.acpl_label_suffix' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Location Checkin Alert') %]" path='hold.acpl_checkin_alert' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Location Is Deleted') %]" path='hold.acpl_deleted' datatype="bool" hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Location URL') %]" path='hold.acpl_url' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Copy Location Order') %]" path='hold.copy_location_order_position' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Default Estimated Wait Time') %]" path='hold.default_estimated_wait' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Minimum Estimated Wait Time') %]" path='hold.min_estimated_wait' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Peer Hold Count') %]" path='hold.other_holds' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Total Wait Time') %]" path='hold.total_wait_time' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Notify Count') %]" path='hold.notification_count' hidden></eg-grid-field>
+ <eg-grid-field label="[% l('Last Notify Time') %]" path='hold.last_notification_time' datatype="timestamp" hidden></eg-grid-field>
+
+</eg-grid>
conjoinedSvc.fetch($scope.record_id).then(function(){
$scope.conjoinedGridDataProvider.refresh();
});
- egHolds.fetch_holds(hold_ids).then($scope.hold_grid_data_provider.refresh);
init_parts_url();
$location.update_path('/cat/catalog/record/' + $scope.record_id);
// update_path() bypasses the controller for path
var provider = egGridDataProvider.instance({});
$scope.hold_grid_data_provider = provider;
$scope.grid_actions = egHoldGridActions;
- $scope.grid_actions.refresh = function () { provider.refresh() };
+ $scope.grid_actions.refresh = function () { holds = []; hold_count = 0; provider.refresh() };
$scope.hold_grid_controls = {};
- var hold_ids = []; // current list of holds
- function fetchHolds(offset, count) {
- var ids = hold_ids.slice(offset, offset + count);
-
- return egHolds.fetch_holds(ids).then(null, null,
- function(hold_data) {
- return hold_data;
- }
- );
- }
-
+ var holds = []; // current list of holds
+ var hold_count = 0;
provider.get = function(offset, count) {
if ($scope.record_tab != 'holds') return $q.when();
- var deferred = $q.defer();
- hold_ids = []; // no caching ATM
- // open a determinate progress dialog, max value set below.
- egProgressDialog.open({max : 1, value : 0});
+ // see if we have the requested range cached
+ if (holds[offset]) {
+ return provider.arrayNotifier(holds, offset, count);
+ }
- // fetch the IDs
- egCore.net.request(
- 'open-ils.circ',
- 'open-ils.circ.holds.retrieve_all_from_title',
- egCore.auth.token(), $scope.record_id,
- {pickup_lib : egCore.org.descendants($scope.pickup_ou.id(), true)}
- ).then(
- function(hold_data) {
- hold_ids = []; // clear the list of ids, hack to avoid dups
- // TODO: fix the underlying problem, which is that
- // this gets called twice when switching to the holds
- // tab; once explicitly, and once via the change handler
- // on the OU selector
- angular.forEach(hold_data, function(list, type) {
- hold_ids = hold_ids.concat(list);
- });
+ hold_count = 0;
+ holds = [];
+ var restrictions = {
+ is_staff_request : 'true',
+ fulfillment_time : null,
+ cancel_time : null,
+ record_id : $scope.record_id,
+ pickup_lib : egCore.org.descendants($scope.pickup_ou.id(), true)
+ };
- // Set the max value of the progress bar to the lesser of
- // the total number of holds to fetch or the page size
- // of the grid.
- egProgressDialog.update(
- {max : Math.min(hold_ids.length, count)});
-
- var holds_fetched = 0;
- fetchHolds(offset, count)
- .then(deferred.resolve, null,
- function(hold_data) {
- holds_fetched++;
- deferred.notify(hold_data);
- egProgressDialog.increment();
+ var order_by = [{ capture_time : null }];
+ if (provider.sort && provider.sort.length) {
+ order_by = [];
+ angular.forEach(provider.sort, function (c) {
+ if (!angular.isObject(c)) {
+ if (c.match(/^hold\./)) {
+ var i = c.replace('hold.','');
+ var ob = {};
+ ob[i] = null;
+ order_by.push(ob);
}
- )['finally'](egProgressDialog.close);
+ } else {
+ var i = Object.keys(c)[0];
+ var direction = c[i];
+ if (i.match(/^hold\./)) {
+ i = i.replace('hold.','');
+ var ob = {}
+ ob[i] = {dir:direction};
+ order_by.push(ob);
+ }
+ }
+ });
+ }
+
+ egProgressDialog.open({max : 1, value : 0});
+ var first = true;
+ return egHolds.fetch_wide_holds(
+ restrictions,
+ order_by
+ ).then(function () {
+ return provider.arrayNotifier(holds, offset, count);
+ },
+ null,
+ function(hold_data) {
+ if (first) {
+ hold_count = hold_data;
+ first = false;
+ egProgressDialog.update({max:hold_count});
+ } else {
+ egProgressDialog.increment();
+ var new_item = { id : hold_data.id, hold : hold_data };
+ new_item.status_string =
+ egCore.strings['HOLD_STATUS_' + hold_data.hold_status]
+ || hold_data.hold_status;
+
+ holds.push(new_item);
+ }
}
- );
+ ).finally(egProgressDialog.close);
- return deferred.promise;
}
$scope.detail_view = function(action, user_data, items) {
if (h = items[0]) {
- $scope.detail_hold_id = h.hold.id();
+ $scope.detail_hold_id = h.hold.id;
}
}
$scope.pickup_ou = egCore.org.get(egCore.auth.user().ws_ou());
$scope.pickup_ou_changed = function(org) {
$scope.pickup_ou = org;
+ holds = []
+ hold_count = 0;
provider.refresh();
}
+ function map_prefix_to_subhash (h,pf) {
+ var newhash = {};
+ angular.forEach(Object.keys(h), function (k) {
+ if (k.startsWith(pf)) {
+ var nk = k.substr(pf.length);
+ newhash[nk] = h[k];
+ }
+ });
+ return newhash;
+ }
+
$scope.print_holds = function() {
- var holds = [];
- angular.forEach($scope.hold_grid_controls.allItems(), function(item) {
- holds.push({
- hold : egCore.idl.toHash(item.hold),
- patron_last : item.patron_last,
- patron_alias : item.patron_alias,
- patron_barcode : item.patron_barcode,
- copy : egCore.idl.toHash(item.copy),
- volume : egCore.idl.toHash(item.volume),
- title : item.mvr.title(),
- author : item.mvr.author()
+ var pholds = [];
+ angular.forEach(holds, function(item) {
+ pholds.push({
+ hold : item.hold,
+ status_string : item.status_string,
+ patron_first : item.hold.usr_first_given_name,
+ patron_last : item.hold.usr_family_name,
+ patron_alias : item.hold.usr_alias,
+ patron_barcode : item.hold.ucard_barcode,
+ copy : map_prefix_to_subhash(item.hold,'cp_'),
+ volume : map_prefix_to_subhash(item.hold,'cn_'),
+ title : item.hold.title,
+ author : item.hold.author
});
});
egCore.print.print({
context : 'receipt',
template : 'holds_for_bib',
- scope : {holds : holds}
+ scope : {holds : pholds}
});
}
// UI presents this option as "all holds"
$scope.transfer_holds_to_marked = function() {
var hold_ids = $scope.hold_grid_controls.allItems().map(
- function(hold_data) {return hold_data.hold.id()});
+ function(hold_data) {return hold_data.hold.id});
egHolds.transfer_to_marked_title(hold_ids);
}
.controller('HoldsShelfCtrl',
- ['$scope','$q','$routeParams','$window','$location','egCore','egHolds','egHoldGridActions','egCirc','egGridDataProvider',
-function($scope , $q , $routeParams , $window , $location , egCore , egHolds , egHoldGridActions , egCirc , egGridDataProvider) {
+ ['$scope','$q','$routeParams','$window','$location','egCore','egHolds','egHoldGridActions','egCirc','egGridDataProvider','egProgressDialog',
+function($scope , $q , $routeParams , $window , $location , egCore , egHolds , egHoldGridActions , egCirc , egGridDataProvider , egProgressDialog) {
$scope.detail_hold_id = $routeParams.hold_id;
var hold_ids = [];
$scope.gridControls = {};
$scope.grid_actions = egHoldGridActions;
- function fetch_holds(offset, count) {
- var ids = hold_ids.slice(offset, offset + count);
- return egHolds.fetch_holds(ids).then(null, null,
- function(hold_data) {
- holds.push(hold_data);
- return hold_data; // to the grid
- }
- );
- }
-
var provider = egGridDataProvider.instance({});
$scope.gridDataProvider = provider;
function refresh_page() {
+ hold_count = 0;
holds = [];
hold_ids = [];
provider.refresh();
return provider.arrayNotifier(holds, offset, count);
}
- // see if we have the holds IDs for this range already loaded
- if (hold_ids[offset]) {
- return fetch_holds(offset, count);
- }
+ // if in clear mode...
+ if (clear_mode && holds.length) {
+ holds = holds.filter(function(h) { return h.hold.clear_me == 't' });
+ }
- var deferred = $q.defer();
- hold_ids = [];
+ hold_count = 0;
holds = [];
+ var restrictions = {
+ is_staff_request : 'true',
+ capture_time : { not : null },
+ cs_id : 8, // on holds shelf
+ fulfillment_time : null,
+ current_shelf_lib : $scope.pickup_ou.id()
+ };
+
+ var order_by = [{ capture_time : null }];
+ if (provider.sort && provider.sort.length) {
+ order_by = [];
+ angular.forEach(provider.sort, function (c) {
+ if (!angular.isObject(c)) {
+ if (c.match(/^hold\./)) {
+ var i = c.replace('hold.','');
+ var ob = {};
+ ob[i] = null;
+ order_by.push(ob);
+ }
+ } else {
+ var i = Object.keys(c)[0];
+ var direction = c[i];
+ if (i.match(/^hold\./)) {
+ i = i.replace('hold.','');
+ var ob = {}
+ ob[i] = {dir:direction};
+ order_by.push(ob);
+ }
+ }
+ });
+ }
- var method = 'open-ils.circ.captured_holds.id_list.on_shelf.retrieve.authoritative.atomic';
- if (clear_mode)
- method = 'open-ils.circ.captured_holds.id_list.expired_on_shelf_or_wrong_shelf.retrieve.atomic';
-
- egCore.net.request(
- 'open-ils.circ', method,
- egCore.auth.token(), $scope.pickup_ou.id()
-
- ).then(function(ids) {
- if (!ids.length) {
- deferred.resolve();
- return;
+ egProgressDialog.open({max : 1, value : 0});
+ var first = true;
+ return egHolds.fetch_wide_holds(
+ restrictions,
+ order_by
+ ).then(function () {
+ return provider.arrayNotifier(holds, offset, count);
+ },
+ null,
+ function(hold_data) {
+ if (first) {
+ hold_count = hold_data;
+ first = false;
+ egProgressDialog.update({max:hold_count});
+ } else {
+ egProgressDialog.increment();
+ var new_item = { id : hold_data.id, hold : hold_data };
+ new_item.status_string =
+ egCore.strings['HOLD_STATUS_' + hold_data.hold_status]
+ || hold_data.hold_status;
+
+ if (clear_mode) {
+ if (hold_data.clear_me == 't') holds.push(new_item);
+ } else {
+ holds.push(new_item);
+ }
+ }
}
-
- hold_ids = ids;
- fetch_holds(offset, count)
- .then(deferred.resolve, null, deferred.notify);
- });
-
- return deferred.promise;
+ ).finally(egProgressDialog.close);
}
// re-draw the grid when user changes the org selector
$scope.detail_view = function(action, user_data, items) {
if (h = items[0]) {
- $location.path('/circ/holds/shelf/' + h.hold.id());
+ $location.path('/circ/holds/shelf/' + h.hold.id);
}
}
// when the detail hold is fetched (and updated), update the bib
// record summary display record id.
$scope.set_hold = function(hold_data) {
- $scope.detail_hold_record_id = hold_data.mvr.doc_id();
+ $scope.detail_hold_record_id = hold_data.hold.record_id;
}
// manage active vs. clearable holds display
angular.forEach(resp, function(info) {
if (info.action) {
var grid_item = holds.filter(function(item) {
- return item.hold.id() == info.hold_details.id
+ return item.hold.id == info.hold_details.id
})[0];
// there will be no grid item if the hold is off-page
);
}
- $scope.print_list_progress = null;
+ function map_prefix_to_subhash (h,pf) {
+ var newhash = {};
+ angular.forEach(Object.keys(h), function (k) {
+ if (k.startsWith(pf)) {
+ var nk = k.substr(pf.length);
+ newhash[nk] = h[k];
+ }
+ });
+ return newhash;
+ }
+
$scope.print_shelf_list = function() {
var print_holds = [];
- $scope.print_list_loading = true;
- $scope.print_list_progress = 0;
+ angular.forEach(holds, function(hold_data) {
+ var phold = {};
+ print_holds.push(phold);
- // collect the full list of holds
- var method = 'open-ils.circ.captured_holds.id_list.on_shelf.retrieve.authoritative.atomic';
- if (clear_mode)
- method = 'open-ils.circ.captured_holds.id_list.expired_on_shelf_or_wrong_shelf.retrieve.atomic';
- egCore.net.request(
- 'open-ils.circ',
- method,
- egCore.auth.token(), $scope.pickup_ou.id()
- ).then( function(idlist) {
-
- egHolds.fetch_holds(idlist).then(
- function () {
- console.debug('printing ' + print_holds.length + ' holds');
- // holds fetched, send to print
- egCore.print.print({
- context : 'default',
- template : 'hold_shelf_list',
- scope : {holds : print_holds}
- })
- },
- null,
- function(hold_data) {
- $scope.print_list_progress++;
- egHolds.local_flesh(hold_data);
- print_holds.push(hold_data);
- hold_data.title = hold_data.mvr.title();
- hold_data.author = hold_data.mvr.author();
- hold_data.hold = egCore.idl.toHash(hold_data.hold);
- hold_data.copy = egCore.idl.toHash(hold_data.copy);
- hold_data.volume = egCore.idl.toHash(hold_data.volume);
- hold_data.part = egCore.idl.toHash(hold_data.part);
- }
- )
- }).finally(function() {
- $scope.print_list_loading = false;
- $scope.print_list_progress = null;
+ phold.status_string = hold_data.status_string;
+
+ phold.patron_first = hold_data.hold.usr_first_given_name;
+ phold.patron_last = hold_data.hold.usr_family_name;
+ phold.patron_alias = hold_data.hold.usr_alias;
+ phold.patron_barcode = hold_data.hold.ucard_barcode;
+
+ phold.title = hold_data.hold.title;
+ phold.author = hold_data.hold.author;
+
+ phold.hold = hold_data.hold;
+ phold.copy = map_prefix_to_subhash(hold_data.hold, 'cp_');
+ phold.volume = map_prefix_to_subhash(hold_data.hold, 'cn_');
+ phold.part = map_prefix_to_subhash(hold_data.hold, 'p_');
+ });
+
+ console.log(print_holds);
+
+ return egCore.print.print({
+ context : 'default',
+ template : 'hold_shelf_list',
+ scope : {holds : print_holds}
});
}
var service = {};
+ service.fetch_wide_holds = function(restrictions, order_by, limit, offset) {
+ return egCore.net.request(
+ 'open-ils.circ',
+ 'open-ils.circ.hold.wide_hash.stream',
+ egCore.auth.token(),
+ restrictions, order_by, limit, offset
+ );
+ }
+
service.fetch_holds = function(hold_ids) {
var deferred = $q.defer();
return egHolds.cancel_holds(hold_ids).then(service.refresh);
}
+ service.cancel_wide_hold = function(items) {
+ var hold_ids = items.filter(function(item) {
+ return !item.hold.cancel_time;
+ }).map(function(item) {return item.hold.id});
+
+ return egHolds.cancel_holds(hold_ids).then(service.refresh);
+ }
+
service.uncancel_hold = function(items) {
var hold_ids = items.filter(function(item) {
return item.hold.cancel_time();
return egHolds.uncancel_holds(hold_ids).then(service.refresh);
}
+ service.uncancel_wide_hold = function(items) {
+ var hold_ids = items.filter(function(item) {
+ return item.hold.cancel_time;
+ }).map(function(item) {return item.hold.id});
+
+ return egHolds.uncancel_holds(hold_ids).then(service.refresh);
+ }
+
// jump to circ list for either 1) the targeted copy or
// 2) the hold target copy for copy-level holds
service.show_recent_circs = function(items) {
});
}
+ // jump to circ list for either 1) the targeted copy or
+ // 2) the hold target copy for copy-level holds
+ service.show_recent_circs_wide = function(items) {
+ var focus = items.length == 1;
+ angular.forEach(items, function(item) {
+ if (item.hold.cp_id) {
+ var url = egCore.env.basePath +
+ '/cat/item/' +
+ item.hold.cp_id +
+ '/circ_list';
+ $timeout(function() { var x = $window.open(url, '_blank'); if (focus) x.focus() });
+ }
+ });
+ }
+
service.show_patrons = function(items) {
var focus = items.length == 1;
angular.forEach(items, function(item) {
});
}
+ service.show_patrons_wide = function(items) {
+ var focus = items.length == 1;
+ angular.forEach(items, function(item) {
+ var url = egCore.env.basePath +
+ 'circ/patron/' +
+ item.hold.usr_id +
+ '/holds';
+ $timeout(function() { var x = $window.open(url, '_blank'); if (focus) x.focus() });
+ });
+ }
+
service.show_holds_for_title = function(items) {
var focus = items.length == 1;
angular.forEach(items, function(item) {
});
}
+ service.show_holds_for_title_wide = function(items) {
+ var focus = items.length == 1;
+ angular.forEach(items, function(item) {
+ var url = egCore.env.basePath +
+ 'cat/catalog/record/' +
+ item.hold.record_id +
+ '/holds';
+ $timeout(function() { var x = $window.open(url, '_blank'); if (focus) x.focus() });
+ });
+ }
+
function generic_update(items, action) {
if (!items.length) return $q.when();
return egHolds[action](hold_ids).then(service.refresh);
}
+ function generic_update_wide(items, action) {
+ if (!items.length) return $q.when();
+ var hold_ids = items.map(function(item) {return item.hold.id});
+ return egHolds[action](hold_ids).then(service.refresh);
+ }
+
service.set_copy_quality = function(items) {
generic_update(items, 'set_copy_quality'); }
service.edit_pickup_lib = function(items) {
service.transfer_to_marked_title = function(items) {
generic_update(items, 'transfer_to_marked_title'); }
+ service.set_copy_quality_wide = function(items) {
+ generic_update_wide(items, 'set_copy_quality'); }
+ service.edit_pickup_lib_wide = function(items) {
+ generic_update_wide(items, 'edit_pickup_lib'); }
+ service.edit_notify_prefs_wide = function(items) {
+ generic_update_wide(items, 'edit_notify_prefs'); }
+ service.edit_dates_wide = function(items) {
+ generic_update_wide(items, 'edit_dates'); }
+ service.suspend_wide = function(items) {
+ generic_update_wide(items, 'suspend_holds'); }
+ service.activate_wide = function(items) {
+ generic_update_wide(items, 'activate_holds'); }
+ service.set_top_of_queue_wide = function(items) {
+ generic_update_wide(items, 'set_top_of_queue'); }
+ service.clear_top_of_queue_wide = function(items) {
+ generic_update_wide(items, 'clear_top_of_queue'); }
+ service.transfer_to_marked_title_wide = function(items) {
+ generic_update_wide(items, 'transfer_to_marked_title'); }
+
service.mark_damaged = function(items) {
angular.forEach(items, function(item) {
if (item.copy) {
});
}
+ service.mark_damaged_wide = function(items) {
+ angular.forEach(items, function(item) {
+ if (item.copy) {
+ egCirc.mark_damaged({
+ id: item.hold.cp_id,
+ barcode: item.hold.cp_barcode
+ }).then(service.refresh);
+ }
+ });
+ }
+
service.mark_missing = function(items) {
var copy_ids = items
.filter(function(item) { return Boolean(item.copy) })
egCirc.mark_missing(copy_ids).then(service.refresh);
}
+ service.mark_missing_wide = function(items) {
+ var copy_ids = items
+ .filter(function(item) { return Boolean(item.hold.cp_id) })
+ .map(function(item) { return item.hold.cp_id });
+ if (copy_ids.length)
+ egCirc.mark_missing(copy_ids).then(service.refresh);
+ }
+
service.retarget = function(items) {
var hold_ids = items.map(function(item) { return item.hold.id() });
egHolds.retarget(hold_ids).then(service.refresh);
}
+ service.retarget_wide = function(items) {
+ var hold_ids = items.map(function(item) { return item.hold.id });
+ egHolds.retarget(hold_ids).then(service.refresh);
+ }
+
return service;
}])
} else if (value === undefined) {
return;
}
- $window.localStorage.setItem(key, jsonified);
+ try {
+ $window.localStorage.setItem(key, jsonified);
+ } catch (e) {
+ console.log('localStorage.setItem (overwrite) failed for '+key+': ', e);
+ }
}
service.appendItem = function(key, value) {
jsonified = JSON.stringify(value);
var old_value = $window.localStorage.getItem(key) || '';
- $window.localStorage.setItem( key, old_value + jsonified );
+ try {
+ $window.localStorage.setItem( key, old_value + jsonified );
+ } catch (e) {
+ console.log('localStorage.setItem (append) failed for '+key+': ', e);
+ }
}
// Set the value for the given key.