Serials: support predicting issuances until a specified end date
authorsenator <senator@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Sun, 12 Sep 2010 00:12:26 +0000 (00:12 +0000)
committersenator <senator@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Sun, 12 Sep 2010 00:12:26 +0000 (00:12 +0000)
Previously you could specify a number of issues, or possibly a final holding,
but if you haven't created the final holding yet, but you know when the
subscription ends, this can be useful.

git-svn-id: svn://svn.open-ils.org/ILS/trunk@17607 dcc99617-32d9-48b4-a31d-7c20da2025e4

Open-ILS/src/perlmods/OpenILS/Application/Serial.pm
Open-ILS/src/perlmods/OpenILS/Utils/MFHD.pm

index 42ccf41..574f256 100644 (file)
@@ -60,6 +60,7 @@ my %MFHD_NAMES_BY_TAG = (  '853' => $MFHD_NAMES[0],
 my %MFHD_TAGS_BY_NAME = (  $MFHD_NAMES[0] => '853',
                         $MFHD_NAMES[1] => '854',
                         $MFHD_NAMES[2] => '855');
+my $_strp_date = new DateTime::Format::Strptime(pattern => '%F');
 
 # helper method for conforming dates to ISO8601
 sub _cleanse_dates {
@@ -629,7 +630,9 @@ sub make_predictions {
         my $options = {
                 'caption' => $caption_field,
                 'scap_id' => $scap->id,
-                'num_to_predict' => $args->{num_to_predict}
+                'num_to_predict' => $args->{num_to_predict},
+                'end_date' => defined $args->{end_date} ?
+                    $_strp_date->parse_datetime($args->{end_date}) : undef
                 };
         if ($args->{base_issuance}) { # predict from a given issuance
             $options->{predict_from} = _revive_holding($args->{base_issuance}->holding_code, $caption_field, 1); # fresh MFHD Record, so we simply default to 1 for seqno
@@ -708,6 +711,7 @@ sub _generate_issuance_values {
     my $caption = $options->{caption};
     my $scap_id = $options->{scap_id};
     my $num_to_predict = $options->{num_to_predict};
+    my $end_date = $options->{end_date};
     my $predict_from = $options->{predict_from};   # issuance to predict from
     #my $last_rec_date = $options->{last_rec_date};   # expected or actual
 
@@ -734,12 +738,11 @@ sub _generate_issuance_values {
 # add a note marker for system use (?)
     $predict_from->notes('private', ['AUTOGEN']);
 
-    my $strp = new DateTime::Format::Strptime(pattern => '%F');
     my $pub_date;
     my @issuance_values;
-    my @predictions = $mfhd->generate_predictions({'base_holding' => $predict_from, 'num_to_predict' => $num_to_predict});
+    my @predictions = $mfhd->generate_predictions({'base_holding' => $predict_from, 'num_to_predict' => $num_to_predict, 'end_date' => $end_date});
     foreach my $prediction (@predictions) {
-        $pub_date = $strp->parse_datetime($prediction->chron_to_date);
+        $pub_date = $_strp_date->parse_datetime($prediction->chron_to_date);
         push(
                 @issuance_values,
                 {
index 8fd76c9..48f00cb 100644 (file)
@@ -19,6 +19,8 @@ sub new {
     my $class = ref($proto) || $proto;
     my $self  = shift;
 
+    $self->{_strp_date} = new DateTime::Format::Strptime(pattern => '%F');
+
     $self->{_mfhd_CAPTIONS} = {};
     $self->{_mfhd_COMPRESSIBLE} = (substr($self->leader, 17, 1) =~ /[45]/);
 
@@ -250,6 +252,13 @@ sub holdings {
       values %{$self->{_mfhd_HOLDINGS}->{$field}->{$capid}};
 }
 
+sub _holding_date {
+    my $self = shift;
+    my $holding = shift;
+
+    return $self->{_strp_date}->parse_datetime($holding->chron_to_date);
+}
+
 #
 # generate_predictions()
 # Accepts a hash ref of options initially defined as:
@@ -257,6 +266,8 @@ sub holdings {
 # num_to_predict : the number of issues you wish to predict
 # OR
 # end_holding : holding field ref, keep predicting until you meet or exceed it
+# OR
+# end_date : keep predicting until you exceed this
 #
 # The basic method is to first convert to a single holding if compressed, then
 # increment the holding and save the resulting values to @predictions.
@@ -270,6 +281,7 @@ sub generate_predictions {
     my $base_holding   = $options->{base_holding};
     my $num_to_predict = $options->{num_to_predict};
     my $end_holding    = $options->{end_holding};
+    my $end_date       = $options->{end_date};
     my $max_to_predict = $options->{max_to_predict} || 10000; # fail-safe
 
     if (!defined($base_holding)) {
@@ -301,6 +313,18 @@ sub generate_predictions {
             }
             $next_holding = $curr_holding->increment->clone;
         }
+    } elsif (defined($end_date)) {
+        my $next_holding = $curr_holding->increment->clone;
+        my $num_predicted = 0;
+        while ($self->_holding_date($next_holding) <= $end_date) {
+            push(@predictions, $next_holding);
+            $num_predicted++;
+            if ($num_predicted >= $max_to_predict) {
+                carp("Maximum prediction count exceeded");
+                last;
+            }
+            $next_holding = $curr_holding->increment->clone;
+        }
     }
 
     return @predictions;