Refactor formatting code to properly handle chronology
authordjfiander <djfiander@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Thu, 27 Nov 2008 01:58:40 +0000 (01:58 +0000)
committerdjfiander <djfiander@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Thu, 27 Nov 2008 01:58:40 +0000 (01:58 +0000)
information stored in the enumeration fields (well, I think it's
handling it properly; it hasn't been tested yet for that case).

Also refactored basic next/prediction code to handle the same
situation. Basically this is all minor stuff that needs to be
done, but allows me to avoid working on actually taking a stab at
predicting the date of the next issue, but that's pretty much all
that's left to do for this iteration of the code.

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

Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Holding.pm

index e0927ee..f0bc0a9 100755 (executable)
@@ -61,10 +61,11 @@ sub new {
     return $self;
 }
 
-sub format {
+sub format_chron {
     my $self = shift;
     my $caption = $self->{CAPTION};
-    my $str = "";
+    my @keys;
+    my $str = '';
     my %month = ( '01' => 'Jan.', '02' => 'Feb.', '03' => 'Mar.',
                  '04' => 'Apr.', '05' => 'May ', '06' => 'Jun.',
                  '07' => 'Jul.', '08' => 'Aug.', '09' => 'Sep.',
@@ -72,66 +73,90 @@ sub format {
                  '21' => 'Spring', '22' => 'Summer',
                  '23' => 'Autumn', '24' => 'Winter' );
 
-    # Enumerations
-    foreach my $key ('a'..'f') {
+    @keys = @_;
+    foreach my $i (0 .. @keys) {
+       my $key = $keys[$i];
        my $capstr;
+       my $chron;
+       my $sep;
 
        last if !defined $caption->caption($key);
 
-#      printf("fmt %s: '%s'\n", $key, $caption->caption($key));
-
        $capstr = $caption->caption($key);
-       if (substr($capstr, 0, 1) eq '(') {
+       if (substr($capstr,0,1) eq '(') {
            # a caption enclosed in parentheses is not displayed
            $capstr = '';
        }
-       $str .= ($key eq 'a' ? "" : ':') . $capstr . $self->{ENUMS}->{$key}->{HOLDINGS};
+
+       # If this is the second level of chronology, then it's
+       # likely to be a month or season, so we should use the
+       # string name rather than the number given.
+       if (($i == 1) && exists $month{$self->{CHRON}->{$key}}) {
+           $chron = $month{$self->{CHRON}->{$key}};
+       } else {
+           $chron = $self->{CHRON}->{$key};
+       }
+
+
+       $str .= (($i == 0 || $str =~ /[. ]$/) ? '' : ':') . $capstr . $chron;
     }
 
-    # Chronology
-    if (defined $caption->caption('i')) {
-       $str .= '(';
-       foreach my $key ('i'..'l') {
+    return $str;
+}
+
+sub format {
+    my $self = shift;
+    my $caption = $self->{CAPTION};
+    my $str = "";
+
+    if ($caption->enumeration_is_chronology) {
+       # if issues are identified by chronology only, then the
+       # chronology data is stored in the enumeration subfields,
+       # so format those fields as if they were chronological.
+       $str = $self->format_chron('a'..'f');
+    } else {
+       # OK, there is enumeration data and maybe chronology
+       # data as well, format both parts appropriately
+
+       # Enumerations
+       foreach my $key ('a'..'f') {
            my $capstr;
-           my $chron;
-           my $sep;
 
            last if !defined $caption->caption($key);
 
+           #   printf("fmt %s: '%s'\n", $key, $caption->caption($key));
+
            $capstr = $caption->caption($key);
-           if (substr($capstr,0,1) eq '(') {
+           if (substr($capstr, 0, 1) eq '(') {
                # a caption enclosed in parentheses is not displayed
                $capstr = '';
            }
-
-           # If this is the second level of chronology, then it's
-           # likely to be a month or season, so we should use the
-           # string name rather than the number given.
-           if ($key eq 'j' && exists $month{$self->{CHRON}->{$key}}) {
-               $chron = $month{$self->{CHRON}->{$key}};
-           } else {
-               $chron = $self->{CHRON}->{$key};
-           }
-
-
-           $str .= (($key eq 'i' || $str =~ /[. ]$/) ? '' : ':') . $capstr . $chron;
-       }
-       $str .= ')';
-    }
-
-    if (exists $caption->{ENUMS}->{'g'}) {
-       # There's at least one level of alternative enumeration
-       $str .= '=';
-       foreach my $key ('g', 'h') {
-           $str .= ($key eq 'g' ? '' : ':') . $caption->caption($key) . $self->{ENUMS}->{$key}->{HOLDINGS};
+           $str .= ($key eq 'a' ? "" : ':') . $capstr . $self->{ENUMS}->{$key}->{HOLDINGS};
        }
 
-       if (exists $caption->{CHRONS}->{m}) {
-           # Alternative Chronology
+       # Chronology
+       if (defined $caption->caption('i')) {
            $str .= '(';
-           $str .= $caption->caption('m') . $self->{ENUMS}->{m}->{HOLDINGS};
+           $str .= $self->format_chron('i'..'l');
            $str .= ')';
        }
+
+       if (exists $caption->{ENUMS}->{'g'}) {
+           # There's at least one level of alternative enumeration
+           $str .= '=';
+           foreach my $key ('g', 'h') {
+               $str .= ($key eq 'g' ? '' : ':') . $caption->caption($key) . $self->{ENUMS}->{$key}->{HOLDINGS};
+           }
+
+           # This assumes that alternative chronology is only ever
+           # provided if there is an alternative enumeration.
+           if (exists $caption->{CHRONS}->{m}) {
+               # Alternative Chronology
+               $str .= '(';
+               $str .= $caption->caption('m') . $self->{ENUMS}->{m}->{HOLDINGS};
+               $str .= ')';
+           }
+       }
     }
 
     # Public Note
@@ -149,6 +174,15 @@ sub format {
     return $str;
 }
 
+sub next_date {
+    my $self = shift;
+    my $next = shift;
+    my @keys = @_;
+
+    my $caption = $self->{CAPTION};
+}
+
+
 # next: Given a holding statement, return a hash containing the 
 # enumeration values for the next issues, whether we hold it or not
 #
@@ -158,85 +192,94 @@ sub next {
     my $next = {};
     my $carry;
 
+    # Initialize $next with current enumeration & chronology, then
+    # we can just operate on $next, based on the contents of the caption
     foreach my $key ('a' .. 'h') {
-       next if !exists $self->{ENUMS}->{$key};
-       $next->{$key} = $self->{ENUMS}->{$key}->{HOLDINGS};
+       $next->{$key} = $self->{ENUMS}->{$key}->{HOLDINGS}
+         if exists $self->{ENUMS}->{$key};
     }
 
-    # First handle any "alternative enumeration", since they're
-    # a lot simpler, and don't depend on the the calendar
-    foreach my $key ('h', 'g') {
-       next if !exists $next->{$key};
-       if (!exists $caption->{ENUMS}->{$key}) {
-           warn "Holding data exists for $key, but no caption specified";
-           $next->{$key} += 1;
-           last;
-       }
-
-       my $cap = $caption->{ENUMS}->{$key};
-       if ($cap->{RESTART} && $cap->{COUNT}
-           && ($next->{$key} == $cap->{COUNT})) {
-           $next->{$key} = 1;
-       } else {
-           $next->{$key} += 1;
-           last;
-       }
+    foreach my $key ('i'..'m') {
+       $next->{$key} = $self->{CHRON}->{$key}
+         if exists $self->{CHRON}->{$key};
     }
 
     if ($caption->enumeration_is_chronology) {
-       # do something
-    }
+       $self->next_date($caption, $next, ('a'..'h'));
+    } else {
+       # First handle any "alternative enumeration", since they're
+       # a lot simpler, and don't depend on the the calendar
+       foreach my $key ('h', 'g') {
+           next if !exists $next->{$key};
+           if (!exists $caption->{ENUMS}->{$key}) {
+               warn "Holding data exists for $key, but no caption specified";
+               $next->{$key} += 1;
+               last;
+           }
 
-    # $carry keeps track of whether we need to carry into the next
-    # higher level of enumeration. It's not actually necessary except
-    # for when the loop ends: if we need to carry from $b into $a
-    # then $carry will be set when the loop ends.
-    # 
-    # We need to keep track of this because there are two different
-    # reasons why we might increment the highest level of enumeration ($a)
-    # 1) we hit the correct number of items in $b (ie, 5th iss of quarterly)
-    # 2) it's the right time of the year.
-    #
-    $carry = 0;
-    foreach my $key (reverse('b'.. 'f')) {
-       next if !exists $next->{$key};
-       if (!exists $caption->{ENUMS}->{$key}) {
-           # Just assume that it increments continuously and give up
-           warn "Holding data exists for $key, but no caption specified";
-           $next->{$key} += 1;
-           $carry = 0;
-           last;
+           my $cap = $caption->{ENUMS}->{$key};
+           if ($cap->{RESTART} && $cap->{COUNT}
+               && ($next->{$key} == $cap->{COUNT})) {
+               $next->{$key} = 1;
+           } else {
+               $next->{$key} += 1;
+               last;
+           }
        }
 
-       my $cap = $caption->{ENUMS}->{$key};
-       if ($cap->{RESTART} && $cap->{COUNT}
-           && ($next->{$key} eq $cap->{COUNT})) {
-           $next->{$key} = 1;
-           $carry = 1;
-       } else {
-           # If I don't need to "carry" beyond here, then I just increment
-           # this level of the enumeration and stop looping, since the
-           # "next" hash has been initialized with the current values
-
-           # NOTE: This DOES NOT take into account the incrementing
-           # of enumerations based on the calendar. (eg: The Economist)
-           $next->{$key} += 1;
-           $carry = 0;
-           last;
+       # $carry keeps track of whether we need to carry into the next
+       # higher level of enumeration. It's not actually necessary except
+       # for when the loop ends: if we need to carry from $b into $a
+       # then $carry will be set when the loop ends.
+       # 
+       # We need to keep track of this because there are two different
+       # reasons why we might increment the highest level of enumeration ($a)
+       # 1) we hit the correct number of items in $b (ie, 5th iss of quarterly)
+       # 2) it's the right time of the year.
+       #
+       $carry = 0;
+       foreach my $key (reverse('b'.. 'f')) {
+           next if !exists $next->{$key};
+           if (!exists $caption->{ENUMS}->{$key}) {
+               # Just assume that it increments continuously and give up
+               warn "Holding data exists for $key, but no caption specified";
+               $next->{$key} += 1;
+               $carry = 0;
+               last;
+           }
+
+           my $cap = $caption->{ENUMS}->{$key};
+           if ($cap->{RESTART} && $cap->{COUNT}
+               && ($next->{$key} eq $cap->{COUNT})) {
+               $next->{$key} = 1;
+               $carry = 1;
+           } else {
+               # If I don't need to "carry" beyond here, then I just increment
+               # this level of the enumeration and stop looping, since the
+               # "next" hash has been initialized with the current values
+
+               # NOTE: This DOES NOT take into account the incrementing
+               # of enumerations based on the calendar. (eg: The Economist)
+               $next->{$key} += 1;
+               $carry = 0;
+               last;
+           }
        }
-    }
 
-    # The easy part is done. There are two things left to do:
-    # 1) Calculate the date of the next issue, if necessary
-    # 2) Increment the highest level of enumeration (either by date
-    #    or because $carry is set because of the above loop
+       # The easy part is done. There are two things left to do:
+       # 1) Calculate the date of the next issue, if necessary
+       # 2) Increment the highest level of enumeration (either by date
+       #    or because $carry is set because of the above loop
 
-    if (!%{$caption->{CHRONS}}) {
-       # The simple case: if there is no chronology specified
-       # then just check $carry and return
-       $next->{'a'} += $carry;
-    } else {
-       # Complicated: figure out date of next issue
+       if (!%{$caption->{CHRONS}}) {
+           # The simple case: if there is no chronology specified
+           # then just check $carry and return
+           $next->{'a'} += $carry;
+       } else {
+           # Figure out date of next issue, then decide if we need
+           # to adjust top level enumeration based on that
+           $self->next_date($caption, $next, ('i'..'m'));
+       }
     }
 
     return($next);