Support multiple volumes in a single year
authordjfiander <djfiander@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Tue, 17 Mar 2009 02:03:13 +0000 (02:03 +0000)
committerdjfiander <djfiander@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Tue, 17 Mar 2009 02:03:13 +0000 (02:03 +0000)
git-svn-id: svn://svn.open-ils.org/ILS/trunk@12551 dcc99617-32d9-48b4-a31d-7c20da2025e4

Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Caption.pm
Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Holding.pm
Open-ILS/src/perlmods/OpenILS/Utils/MFHD/test/mfhd.t

index 0ecd9cd..b5a1113 100755 (executable)
@@ -47,9 +47,12 @@ sub new
            carp '$v specified for top-level enumeration'
              unless defined($last_enum);
            $self->{_mfhdc_ENUMS}->{$last_enum}->{RESTART} = ($val eq 'r');
-       } elsif ($key =~ /[npwxz]/) {
-           # Publication Pattern ('o' == type of unit, 'q'..'t' undefined)
+       } elsif ($key =~ /[npwz]/) {
+           # Publication Pattern info ('o' == type of unit, 'q'..'t' undefined)
            $self->{_mfhdc_PATTERN}->{$key} = $val;
+       } elsif ($key =~ /x/) {
+           # Calendar change can have multiple comma-separated values
+           $self->{_mfhdc_PATTERN}->{x} = [split /,/, $val];
        } elsif ($key eq 'y') {
            # Publication pattern: 'y' is repeatable
            $self->{_mfhdc_PATTERN}->{y} = [] if (!defined $self->{_mfhdc_PATTERN}->{y});
@@ -143,6 +146,12 @@ sub capstr {
     }
 }
 
+sub calendar_change {
+    my $self = shift;
+
+    return $self->{_mfhdc_PATTERN}->{x};
+}
+
 # If items are identified by chronology only, with no separate
 # enumeration (eg, a newspaper issue), then the chronology is
 # recorded in the enumeration subfields $a - $f.  We can tell
index 267ee04..b5b6bef 100755 (executable)
@@ -321,8 +321,8 @@ sub next_date {
        # if $carry is set, the date doesn't matter: we're not
        # going to increment the v. number twice at year-change.
        $next->{a} += $carry;
-    } elsif ($caption->subfield('x')) {
-       my $cal_change = $caption->subfield('x');
+    } elsif (defined $caption->calendar_change) {
+       my $cal_change = $caption->calendar_change;
        my $month;
        my $day;
        my $cur_before;
@@ -334,32 +334,41 @@ sub next_date {
            return;
        }
 
-       if (length($cal_change) == 2) {
-           $month = $cal_change;
-       } elsif (length($cal_change) == 4) {
-           ($month, $day) = unpack("a2a2", $cal_change);
-       }
+       foreach my $change (@{$cal_change}) {
+           my $incr;
 
-#      print "# next_date: month = '$month', day = '$day'\n";
-#      print "# next_date: cur[0] = '$cur[0]', cur[1] = '$cur[1]'\n";
-#      print "# next_date: new[0] = '$new[0]', new[1] = '$new[1]'\n";
+           if (length($change) == 2) {
+               $month = $change;
+           } elsif (length($change) == 4) {
+               ($month, $day) = unpack("a2a2", $change);
+           }
 
-       if ($cur[0] == $new[0]) {
-           # Same year, so a 'simple' month/day comparison will be fine
-           $next->{a} += (!on_or_after($cur[1], $cur[2], $month, $day)
-                          && on_or_after($new[1], $new[2], $month, $day));
-       } else {
-           # @cur is in the year before @new. There are
-           # two possible cases for the calendar change date that
-           # indicate that it's time to change the volume:
-           # (1) the change date is AFTER @cur in the year, or
-           # (2) the change date is BEFORE @new in the year.
-           # 
-           #  -------|------|------X------|------|
-           #       @cur    (1)   Jan 1   (2)   @new
-
-           $next->{a} += (on_or_after($new[1], $new[2], $month, $day)
-                          || !on_or_after($cur[1], $cur[2], $month, $day));
+           #   print "# next_date: month = '$month', day = '$day'\n";
+           #   print "# next_date: cur[0] = '$cur[0]', cur[1] = '$cur[1]'\n";
+           #   print "# next_date: new[0] = '$new[0]', new[1] = '$new[1]'\n";
+
+           if ($cur[0] == $new[0]) {
+               # Same year, so a 'simple' month/day comparison will be fine
+               $incr = (!on_or_after($cur[1], $cur[2], $month, $day)
+                        && on_or_after($new[1], $new[2], $month, $day));
+           } else {
+               # @cur is in the year before @new. There are
+               # two possible cases for the calendar change date that
+               # indicate that it's time to change the volume:
+               # (1) the change date is AFTER @cur in the year, or
+               # (2) the change date is BEFORE @new in the year.
+               # 
+               #  -------|------|------X------|------|
+               #       @cur    (1)   Jan 1   (2)   @new
+
+               $incr = (on_or_after($new[1], $new[2], $month, $day)
+                        || !on_or_after($cur[1], $cur[2], $month, $day));
+           }
+           if ($incr) {
+               # We've got a match, we can stop checking
+               $next->{a} += 1;
+               last;
+           }
        }
     }
 }
index ad725c7..51581ef 100644 (file)
@@ -85,7 +85,7 @@ while ($rec = load_MARC_rec) {
                local $TODO = "unimplemented"
                  if ($field->subfield('z') =~ /^TODO/);
                is_deeply($field->next, right_answer($field),
-                         $field->subfield('8'));
+                         $field->subfield('8') . ': ' . $field->subfield('z'));
            }
        }
     }
@@ -133,7 +133,7 @@ __END__
 245 00 $aMonthly, issue no. continuous, Calendar change: Jan, Jul
 853 20 $86$av.$bno.$u6$vc$i(year)$j(month)$wm$x01,07
 863 41 $86.1$a1$b5$i1990$j05$x|a1|b6|i1990|j06$zMiddle of year, end of vol.
-863 41 $86.2$a1$b6$i1990$j06$x|a2|b7|i1990|j07$zTODO Middle of year, end of vol.
+863 41 $86.2$a1$b6$i1990$j06$x|a2|b7|i1990|j07$zMiddle of year, end of vol.
 863 41 $86.3$a2$b12$i1990$j12$x|a3|b13|i1991|j01$zEnd of year, end of vol.
 
 245 00 $aMonthly, issue no. restarts, Calendar change: Jan, Combined issue: Jan/Feb