}};
};
+ my $ou_sort_param = [$org, $pref_ou ];
+ my $gl = $self->cgi->param('geographic-location');
+ if ($gl) {
+ my $geo = OpenSRF::AppSession->create("open-ils.geo");
+ my $coords = $geo
+ ->request('open-ils.geo.retrieve_coordinates', $org, scalar $gl)
+ ->gather(1);
+ if ($coords
+ && ref($coords)
+ && $$coords{latitude}
+ && $$coords{longitude}
+ ) {
+ push(@$ou_sort_param, $$coords{latitude}, $$coords{longitude});
+ }
+ }
+
# Unsure if we want these in the shared function, leaving here for now
unshift(@{$query->{order_by}},
{ class => "aou", field => 'id',
- transform => 'evergreen.rank_ou', params => [$org, $pref_ou]
+ transform => 'evergreen.rank_ou', params => $ou_sort_param
}
);
push(@{$query->{order_by}},
);
$$ LANGUAGE SQL STABLE;
+-- geolocation-aware variant
+CREATE OR REPLACE FUNCTION evergreen.rank_ou(lib INT, search_lib INT, pref_lib INT, plat FLOAT, plon FLOAT)
+RETURNS INTEGER AS $$
+ SELECT COALESCE(
+
+ -- lib matches search_lib
+ (SELECT CASE WHEN $1 = $2 THEN -20000 END),
+
+ -- lib matches pref_lib
+ (SELECT CASE WHEN $1 = $3 THEN -10000 END),
+
+
+ -- pref_lib is a child of search_lib and lib is a child of pref lib.
+ -- For example, searching CONS, pref lib is SYS1,
+ -- copies at BR1 and BR2 sort to the front.
+ (SELECT distance - 5000
+ FROM actor.org_unit_descendants_distance($3)
+ WHERE id = $1 AND $3 IN (
+ SELECT id FROM actor.org_unit_descendants($2))),
+
+ -- lib is a child of search_lib
+ (SELECT distance FROM actor.org_unit_descendants_distance($2) WHERE id = $1),
+
+ -- all others pay cash
+ 1000
+ ) + ((SELECT CASE WHEN addr.latitude IS NULL THEN 0 ELSE -20038 END) + (earth_distance( -- shortest GC distance is returned, only half the circumfrence is needed
+ ll_to_earth(
+ COALESCE(addr.latitude,plat), -- if the org has no coords, we just
+ COALESCE(addr.longitude,plon) -- force 0 distance and let the above tie-break
+ ),ll_to_earth(plat,plon)
+ ) / 1000)::INT ) -- earth_distance is in meters, convert to kilometers and subtract from largest distance
+ FROM actor.org_unit org
+ LEFT JOIN actor.org_address addr ON (org.billing_address = addr.id)
+ WHERE org.id = $1;
+$$ LANGUAGE SQL STABLE;
+
-- this version exists mainly to accommodate JSON query transform limitations
-- (the transform argument must be an IDL field, not an entire row/object)
-- XXX is there another way?
CREATE EXTENSION intarray;
CREATE EXTENSION pgcrypto;
CREATE EXTENSION unaccent;
+CREATE EXTENSION earthdistance CASCADE;
-- check whether patch can be applied
SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version);
+CREATE EXTENSION earthdistance CASCADE;
+
-- 005.schema.actors.sql
-- CREATE TABLE actor.org_address (
'Administer geographic location services', 'ppl', 'description'))
;
+-- geolocation-aware variant
+CREATE OR REPLACE FUNCTION evergreen.rank_ou(lib INT, search_lib INT, pref_lib INT, plat FLOAT, plon FLOAT)
+RETURNS INTEGER AS $$
+ SELECT COALESCE(
+
+ -- lib matches search_lib
+ (SELECT CASE WHEN $1 = $2 THEN -20000 END),
+
+ -- lib matches pref_lib
+ (SELECT CASE WHEN $1 = $3 THEN -10000 END),
+
+
+ -- pref_lib is a child of search_lib and lib is a child of pref lib.
+ -- For example, searching CONS, pref lib is SYS1,
+ -- copies at BR1 and BR2 sort to the front.
+ (SELECT distance - 5000
+ FROM actor.org_unit_descendants_distance($3)
+ WHERE id = $1 AND $3 IN (
+ SELECT id FROM actor.org_unit_descendants($2))),
+
+ -- lib is a child of search_lib
+ (SELECT distance FROM actor.org_unit_descendants_distance($2) WHERE id = $1),
+
+ -- all others pay cash
+ 1000
+ ) + ((SELECT CASE WHEN addr.latitude IS NULL THEN 0 ELSE -20038 END) + (earth_distance( -- shortest GC distance is returned, only half the circumfrence is needed
+ ll_to_earth(
+ COALESCE(addr.latitude,plat), -- if the org has no coords, we just
+ COALESCE(addr.longitude,plon) -- force 0 distance and let the above tie-break
+ ),ll_to_earth(plat,plon)
+ ) / 1000)::INT ) -- earth_distance is in meters, convert to kilometers and subtract from largest distance
+ FROM actor.org_unit org
+ LEFT JOIN actor.org_address addr ON (org.billing_address = addr.id)
+ WHERE org.id = $1;
+$$ LANGUAGE SQL STABLE;
+
COMMIT;
depth = CGI.param('copy_depth').defined ? CGI.param('copy_depth') : CGI.param('depth').defined ? CGI.param('depth') : ctx.copy_summary.last.depth;
total_copies = ctx.copy_summary.$depth.count;
%]
+[% IF ctx.geo_sort %]
+<form method="GET">
+[% FOREACH p IN CGI.params.keys; NEXT IF p == 'geographic-location' %]
+ <input type="hidden" name="[% p | html %]" value="[% CGI.params.$p | html %]"/>
+[% END %]
+<span with="50%">
+ [% l("Sort by distance from:") %]
+ <input type="text" id="geographic-location-box" name="geographic-location" aria-label="[% l('Enter address or postal code') %]" placeholder="[% l('Enter address/postal code') %]" class="search-box" x-webkit-speech="" value="[% p = 'geographic-location'; CGI.params.$p %]"></input>
+ <button type="submit" class="btn btn-confirm">[% l('Go') %]</button>
+</span>
+</form>
+[% END %]
<table class="container-fluid table table-hover mt-4 miniTable copyTable w-100" >
<thead>
<tr>
%]
[% use_courses = (ctx.get_org_setting(ctx.aou_tree.id, 'circ.course_materials_opt_in') == 1) ? 1 : 0 %]
[% IF ctx.geo_sort %]
+<form method="GET">
+[% FOREACH p IN CGI.params.keys; NEXT IF p == 'geographic-location' %]
+ <input type="hidden" name="[% p | html %]" value="[% CGI.params.$p | html %]"/>
+[% END %]
+<span with="50%">
<th colspan="6">
[% l("Sort by distance from:") %]
- <input type="text" id="geographic-location-box" name="geographic-location" aria-label="[% l('Enter address or postal code') %]" placeholder="[% l('Enter address/postal code') %]" class="search-box" x-webkit-speech=""></input>
- <input id="geographic-location-submit-go" type="submit" value="[% l('Go') %]" class="opac-button" onclick=""></input>
-</th>
+ <input type="text" id="geographic-location-box" name="geographic-location" aria-label="[% l('Enter address or postal code') %]" placeholder="[% l('Enter address/postal code') %]" class="search-box" x-webkit-speech="" value="[% p = 'geographic-location'; CGI.params.$p %]"></input>
+ <button type="submit" class="opac-button">[% l('Go') %]</button>
+</span>
+</form>
[% END %]
<table class="table_no_border_space table_no_cell_pad table_no_border" width="100%" id="rdetails_status">
<thead>