[open-ils-commits] r14045 - in trunk/Open-ILS: examples src/extras src/perlmods/OpenILS/Application/Storage/Publisher (miker)

svn at svn.open-ils.org svn at svn.open-ils.org
Thu Sep 17 16:19:33 EDT 2009


Author: miker
Date: 2009-09-17 16:19:28 -0400 (Thu, 17 Sep 2009)
New Revision: 14045

Modified:
   trunk/Open-ILS/examples/fm_IDL.xml
   trunk/Open-ILS/src/extras/Makefile.install
   trunk/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/action.pm
Log:
loop-based targeting (does not need the views defined the other day ... may remove those at some point), cut the first; org unit weighting for hold targeting

Modified: trunk/Open-ILS/examples/fm_IDL.xml
===================================================================
--- trunk/Open-ILS/examples/fm_IDL.xml	2009-09-17 20:03:30 UTC (rev 14044)
+++ trunk/Open-ILS/examples/fm_IDL.xml	2009-09-17 20:19:28 UTC (rev 14045)
@@ -4879,7 +4879,105 @@
         </fields>
     </class>
 
+    <class id="aufhl" controller="open-ils.cstore" oils_obj:fieldmapper="action::unfulfilled_hold_loops" oils_persist:tablename="action.unfulfilled_hold_loops" oils_persist:readonly="true">
+		<oils_persist:source_definition>
 
+	    SELECT  u.hold,
+	            c.circ_lib,
+	            count(*)
+	      FROM  action.unfulfilled_hold_list u
+	            JOIN asset.copy c ON (c.id = u.current_copy)
+	      GROUP BY 1,2
+
+		</oils_persist:source_definition>
+        <fields>
+            <field reporter:label="Hold ID" name="hold" reporter:datatype="link"/>
+            <field reporter:label="Circulating Library" name="circ_lib" reporter:datatype="link"/>
+            <field reporter:label="Loop Count" name="count" reporter:datatype="int"/>
+        </fields>
+		<links>
+			<link field="hold" reltype="has_a" key="id" map="" class="ahr"/>
+			<link field="circ_lib" reltype="has_a" key="id" map="" class="aou"/>
+		</links>
+    </class>
+
+    <class id="aufhml" controller="open-ils.cstore" oils_obj:fieldmapper="action::unfulfilled_hold_min_loop" oils_persist:tablename="action.unfulfilled_hold_min_loop" oils_persist:readonly="true">
+		<oils_persist:source_definition>
+
+	    SELECT  hold,
+	            min(count)
+	      FROM  action.unfulfilled_hold_loops
+	      GROUP BY 1
+
+		</oils_persist:source_definition>
+        <fields>
+            <field reporter:label="Hold ID" name="hold" reporter:datatype="link"/>
+            <field reporter:label="Min Loop" name="min" reporter:datatype="int"/>
+        </fields>
+		<links>
+			<link field="hold" reltype="has_a" key="id" map="" class="ahr"/>
+		</links>
+    </class>
+
+    <class id="aufhil" controller="open-ils.cstore" oils_obj:fieldmapper="action::unfulfilled_hold_innermost_loop" oils_persist:tablename="action.unfulfilled_hold_innermost_loop" oils_persist:readonly="true">
+		<oils_persist:source_definition>
+
+	    SELECT  DISTINCT l.*
+	      FROM  action.unfulfilled_hold_loops l
+	            JOIN action.unfulfilled_hold_min_loop m USING (hold)
+	      WHERE l.count = m.min
+
+		</oils_persist:source_definition>
+        <fields>
+            <field reporter:label="Hold ID" name="hold" reporter:datatype="link"/>
+            <field reporter:label="Circulating Library" name="circ_lib" reporter:datatype="link"/>
+            <field reporter:label="Loop Count" name="count" reporter:datatype="int"/>
+        </fields>
+		<links>
+			<link field="hold" reltype="has_a" key="id" map="" class="ahr"/>
+			<link field="circ_lib" reltype="has_a" key="id" map="" class="aou"/>
+		</links>
+    </class>
+
+    <class id="aufhmxl" controller="open-ils.cstore" oils_obj:fieldmapper="action::unfulfilled_hold_max_loop" oils_persist:tablename="action.unfulfilled_hold_max_loop" oils_persist:readonly="true">
+		<oils_persist:source_definition>
+
+	    SELECT  hold,
+	            max(count)
+	      FROM  action.unfulfilled_hold_loops
+	      GROUP BY 1
+
+		</oils_persist:source_definition>
+        <fields>
+            <field reporter:label="Hold ID" name="hold" reporter:datatype="link"/>
+            <field reporter:label="Max Loop" name="max" reporter:datatype="int"/>
+        </fields>
+		<links>
+			<link field="hold" reltype="has_a" key="id" map="" class="ahr"/>
+		</links>
+    </class>
+
+    <class id="aufhol" controller="open-ils.cstore" oils_obj:fieldmapper="action::unfulfilled_hold_outermost_loop" oils_persist:tablename="action.unfulfilled_hold_outermost_loop" oils_persist:readonly="true">
+		<oils_persist:source_definition>
+
+	    SELECT  DISTINCT l.*
+	      FROM  action.unfulfilled_hold_loops l
+	            JOIN action.unfulfilled_hold_max_loop m USING (hold)
+	      WHERE l.count = m.max
+
+		</oils_persist:source_definition>
+        <fields>
+            <field reporter:label="Hold ID" name="hold" reporter:datatype="link"/>
+            <field reporter:label="Circulating Library" name="circ_lib" reporter:datatype="link"/>
+            <field reporter:label="Loop Count" name="count" reporter:datatype="int"/>
+        </fields>
+		<links>
+			<link field="hold" reltype="has_a" key="id" map="" class="ahr"/>
+			<link field="circ_lib" reltype="has_a" key="id" map="" class="aou"/>
+		</links>
+    </class>
+
+
 	<!-- ********************************************************************************************************************* -->
 	<!-- What follows is a set of example extensions that are useful for PINES.  Comment out or remove if you don't want them. -->
 	<!-- ********************************************************************************************************************* -->

Modified: trunk/Open-ILS/src/extras/Makefile.install
===================================================================
--- trunk/Open-ILS/src/extras/Makefile.install	2009-09-17 20:03:30 UTC (rev 14044)
+++ trunk/Open-ILS/src/extras/Makefile.install	2009-09-17 20:19:28 UTC (rev 14045)
@@ -214,7 +214,8 @@
     Business::CreditCard::Object \
     Net::Z3950::Simple2ZOOM \
 	UUID::Tiny \
-    SRU
+    SRU \
+    Safe
 
 # Intrepid and Lenny have libmarc-charset-perl, libmarc-xml-perl, libnet-z3950-zoom-perl
 CPAN_MODULES_MARC = \

Modified: trunk/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/action.pm
===================================================================
--- trunk/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/action.pm	2009-09-17 20:03:30 UTC (rev 14044)
+++ trunk/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/action.pm	2009-09-17 20:19:28 UTC (rev 14045)
@@ -989,6 +989,8 @@
 			my $copy_count = @$all_copies;
 
 			# map the potentials, so that we can pick up checkins
+			# XXX Loop-based targeting may require that /only/ copies from this loop should be added to
+			# XXX the potentials list.  If this is the cased, hold_copy_map creation will move down further.
 			$log->debug( "\tMapping ".scalar(@$all_copies)." potential copies for hold ".$hold->id);
 			action::hold_copy_map->create( { hold => $hold->id, target_copy => $_->id } ) for (@$all_copies);
 
@@ -1038,7 +1040,6 @@
 				}
 			}
 
-			#$client->status( new OpenSRF::DomainObject::oilsContinueStatus );
 			my $prox_list = [];
 			$$prox_list[0] =
 			[
@@ -1048,13 +1049,84 @@
 			];
 
 			$all_copies = [grep {$_->circ_lib != $hold->pickup_lib } @good_copies];
+			# $all_copies is now a list of copies not at the pickup library
 
-			#$client->status( new OpenSRF::DomainObject::oilsContinueStatus );
 			my $best = choose_nearest_copy($hold, $prox_list);
 			$client->status( new OpenSRF::DomainObject::oilsContinueStatus );
 
 			if (!$best) {
 				$log->debug("\tNothing at the pickup lib, looking elsewhere among ".scalar(@$all_copies)." copies");
+
+				my $max_loops = $actor->request(
+					'open-ils.actor.ou_setting.ancestor_default' => $lib => 'circ.holds.max_org_unit_target_loops'
+				)->gather(1);
+
+				if (defined($max_loops)) {
+					my %circ_lib_map =  map ( $_->circ_lib => 1 ) @$all_copies;
+					my $circ_lib_list = [keys %circ_lib_map];
+	
+					my $cstore = OpenSRF::AppSession->connect('open-ils.cstore');
+	
+					# Grab the "biggest" loop for this hold so far
+					my $current_loop = $cstore->request(
+						'open-ils.cstore.json_query',
+						{ distinct => 1,
+						  select => { aufhmxl => [max] },
+						  from => 'aufhmxl',
+						  where => { hold => $hold->id}
+						}
+					)->gather(1);
+	
+					$current_loop = $current_loop->{max} if ($current_loop);
+					$current_loop ||= 1;
+	
+					my $exclude_list = $cstore->request(
+						'open-ils.cstore.json_query.atomic',
+						{ distinct => 1,
+						  select => { aufhol => [circ_lib] },
+						  from => 'aufhol',
+						  where => { hold => $hold->id}
+						}
+					)->gather(1);
+	
+					my @keepers;
+					if ($exclude_list && @$exclude_list) {
+						$exclude_list = [map ($_->{circ_lib}) @$exclude_list];
+						# check to see if we've used up every library in the potentials list
+						for my $l ( @$circ_lib_list ) {
+							my $keep = 1;
+							for my $ex ( @$exclude_list ) {
+								if ($ex eq $l) {
+									$keep = 0;
+									last;
+								}
+							}
+							push(@keepers, $l) if ($keep);
+						}
+					} else {
+						@keepers = @$circ_lib_list;
+					}
+	
+					$current_loop++ if (!@keepers);
+	
+					if ($max_loops && $max_loops <= $current_loop) {
+						# We haven't exceeded max_loops yet
+						my @keeper_copies;
+						for my $cp ( @$all_copies ) {
+							push (@keeper_copies, $cp) if ( grep { $_ eq $cp->circ_lib } @keepers );
+						}
+					} else {
+						# We have, and should remove potentials and cancel the hold
+						my @oldmaps = action::hold_copy_map->search( hold => $hold->id );
+						$_->delete for (@oldmaps);
+	
+						$hold->update( { cancel_time => 'now' } );
+						$self->method_lookup('open-ils.storage.transaction.commit')->run;
+						die "OK\n";
+					}
+				}
+
+				$self->{target_weight} = {};
 				$prox_list = create_prox_list( $self, $hold->pickup_lib, $all_copies );
 
 				$client->status( new OpenSRF::DomainObject::oilsContinueStatus );
@@ -1273,12 +1345,12 @@
 	delete $$self{user_filter};
 	return undef;
 }
-__PACKAGE__->register_method(
-	api_name        => 'open-ils.storage.action.hold_request.copy_targeter',
-	api_level       => 0,
-	stream		=> 1,
-	method          => 'hold_copy_targeter',
-);
+#__PACKAGE__->register_method(
+#	api_name        => 'open-ils.storage.action.hold_request.copy_targeter',
+#	api_level       => 0,
+#	stream		=> 1,
+#	method          => 'hold_copy_targeter',
+#);
 
 
 sub copy_hold_capture {
@@ -1376,12 +1448,22 @@
 	my $lib = shift;
 	my $copies = shift;
 
+	my $actor = OpenSRF::AppSession->create('open-ils.actor');
+
 	my @prox_list;
 	for my $cp (@$copies) {
 		my ($prox) = $self->method_lookup('open-ils.storage.asset.copy.proximity')->run( $cp, $lib );
 		next unless (defined($prox));
+
+		# Fetch the weighting value for hold targeting, defaulting to 1
+		$self->{target_weight} ||= $actor->request(
+			'open-ils.actor.ou_setting.ancestor_default' => $lib => 'circ.holds.org_unit_target_weight'
+		)->gather(1) || 1;
+
 		$prox_list[$prox] = [] unless defined($prox_list[$prox]);
-		push @{$prox_list[$prox]}, $cp;
+		for my $w ( 1 .. $self->{target_weight} ) {
+			push @{$prox_list[$prox]}, $cp;
+		}
 	}
 	return \@prox_list;
 }



More information about the open-ils-commits mailing list