Add support for split issue numbers
authordjfiander <djfiander@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Thu, 2 Apr 2009 00:38:53 +0000 (00:38 +0000)
committerdjfiander <djfiander@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Thu, 2 Apr 2009 00:38:53 +0000 (00:38 +0000)
git-svn-id: svn://svn.open-ils.org/ILS/trunk@12758 dcc99617-32d9-48b4-a31d-7c20da2025e4

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

index 2502a5c..cf70493 100755 (executable)
@@ -3,6 +3,8 @@ use strict;
 use integer;
 use Carp;
 
+use Data::Dumper;
+
 use DateTime;
 
 use base 'MARC::Field';
@@ -54,8 +56,8 @@ sub new
            # 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});
+           $self->{_mfhdc_PATTERN}->{y} = []
+             unless exists $self->{_mfhdc_PATTERN}->{y};
            push @{$self->{_mfhdc_PATTERN}->{y}}, $val;
        } elsif ($key eq 'o') {
            # Type of unit
@@ -344,7 +346,9 @@ sub match_issue {
     my $pat = shift;
     my @date = @_;
 
-    # XXX WRITE ME
+    # We handle enumeration patterns separately. This just
+    # ensures that when we're processing chronological patterns
+    # we don't match an enumeration pattern.
     return 0;
 }
 
@@ -409,4 +413,25 @@ sub is_combined {
     return $self->regularity_match('c', @date);
 }
 
+sub enum_is_combined {
+    my $self = shift;
+    my $subfield = shift;
+    my $iss = shift;
+    my $level = ord($subfield) - ord('a') + 1;
+
+    return 0 if !exists $self->{_mfhdc_PATTERN}->{y};
+
+    foreach my $regularity (@{$self->{_mfhdc_PATTERN}->{y}}) {
+       next unless $regularity =~ m/^ce$level/o;
+
+       my @pats = split(/,/, substr($regularity, 3));
+
+       foreach my $pat (@pats) {
+           $pat =~ s|/.+||;    # if it's a combined issue, match the start
+           return 1 if ($iss eq $pat);
+       }
+    }
+
+    return 0;
+}
 1;
index 4029478..99db706 100755 (executable)
@@ -324,9 +324,10 @@ sub next_date {
        $new[$i] = $cur[$i] = $next->{$keys[$i]} if exists $next->{$keys[$i]};
     }
 
-    if ($new[-1] =~ m;.+/.+;) {
-       $new[-1] =~ s|^[^/]+/||;
-    }
+    # If the current issue has a combined date (eg, May/June)
+    # get rid of the first date and base the calculation
+    # on the final date in the combined issue.
+    $new[-1] =~ s|^[^/]+/||;
 
     # If $frequency is not one of the standard codes defined in %increments
     # then there has to be a $yp publication regularity pattern that
@@ -426,6 +427,13 @@ sub next_enum {
            last;
        }
 
+       # If the current issue has a combined issue number (eg, 2/3)
+       # get rid of the first issue number and base the calculation
+       # on the final issue number in the combined issue.
+       if ($next->{$key} =~ m|/|) {
+           $next->{$key} =~ s|^[^/]+/||;
+       }
+
        my $cap = $caption->capfield($key);
        if ($cap->{RESTART} && $cap->{COUNT}
            && ($next->{$key} eq $cap->{COUNT})) {
@@ -436,12 +444,17 @@ sub next_enum {
            # 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;
        }
+
+       # You can't have a combined issue that spans two volumes: no.12/1
+       # is forbidden
+       if ($caption->enum_is_combined($key, $next->{$key})) {
+           $next->{$key} .= '/' . ($next->{$key} + 1);
+       }
+
+       last if !$carry;
     }
 
     # The easy part is done. There are two things left to do: