From 3027b729a319031f405ca94c84a4655f0d578b57 Mon Sep 17 00:00:00 2001 From: djfiander Date: Tue, 17 Mar 2009 02:03:13 +0000 Subject: [PATCH] Support multiple volumes in a single year git-svn-id: svn://svn.open-ils.org/ILS/trunk@12551 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- .../src/perlmods/OpenILS/Utils/MFHD/Caption.pm | 13 ++++- .../src/perlmods/OpenILS/Utils/MFHD/Holding.pm | 61 +++++++++++++--------- .../src/perlmods/OpenILS/Utils/MFHD/test/mfhd.t | 4 +- 3 files changed, 48 insertions(+), 30 deletions(-) diff --git a/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Caption.pm b/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Caption.pm index 0ecd9cd9d3..b5a1113e6d 100755 --- a/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Caption.pm +++ b/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Caption.pm @@ -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 diff --git a/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Holding.pm b/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Holding.pm index 267ee047e4..b5b6befaac 100755 --- a/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Holding.pm +++ b/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Holding.pm @@ -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; + } } } } diff --git a/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/test/mfhd.t b/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/test/mfhd.t index ad725c7eee..51581efc30 100644 --- a/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/test/mfhd.t +++ b/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/test/mfhd.t @@ -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 -- 2.11.0