From: Lebbeous Fogle-Weekley Date: Tue, 29 Nov 2011 19:26:00 +0000 (-0500) Subject: Backport of 850052e7e6b4cb0c64 from master X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=refs%2Fheads%2Fuser%2Fsenator%2F850052e-for-rel_1_6_1;p=working%2FEvergreen.git Backport of 850052e7e6b4cb0c64 from master This *may* fix a problem in 1.6.1.x where calling open-ils.storage.actor.org_unit.closed_date.overlap with an OU argument that has no hours of operation defined sends the storage service into an infinite loop. Not wholly tested. Signed-off-by: Lebbeous Fogle-Weekley --- diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/actor.pm b/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/actor.pm index 343eae6530..6a2eea37d6 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/actor.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/actor.pm @@ -208,7 +208,7 @@ __PACKAGE__->register_method( ); -sub org_closed_overlap { +sub new_org_closed_overlap { my $self = shift; my $client = shift; my $ou = shift; @@ -241,7 +241,7 @@ sub org_closed_overlap { $before = $_dt_parser->parse_datetime( $begin ); $before->subtract( minutes => 1 ); - while ( my $_b = org_closed_overlap($self, $client, $ou, $before->iso8601, -1, 1 ) ) { + while ( my $_b = new_org_closed_overlap($self, $client, $ou, $before->iso8601, -1, 1 ) ) { $before = $_dt_parser->parse_datetime( clense_ISO8601($_b->{start}) ); } $begin = clense_ISO8601($before->iso8601); @@ -251,7 +251,7 @@ sub org_closed_overlap { $after = $_dt_parser->parse_datetime( $end ); $after->add( minutes => 1 ); - while ( my $_a = org_closed_overlap($self, $client, $ou, $after->iso8601, 1, 1 ) ) { + while ( my $_a = new_org_closed_overlap($self, $client, $ou, $after->iso8601, 1, 1 ) ) { $after = $_dt_parser->parse_datetime( clense_ISO8601($_a->{end}) ); } $end = clense_ISO8601($after->iso8601); @@ -280,7 +280,7 @@ sub org_closed_overlap { if (my $closure = actor::org_unit::closed_date->db_Main->selectrow_hashref( $sql, {}, $begin, $ou )) { $before = $_dt_parser->parse_datetime( $begin ); $before->subtract( minutes => 1 ); - while ( my $_b = org_closed_overlap($self, $client, $ou, $before->iso8601, -1 ) ) { + while ( my $_b = new_org_closed_overlap($self, $client, $ou, $before->iso8601, -1 ) ) { $before = $_dt_parser->parse_datetime( clense_ISO8601($_b->{start}) ); } } @@ -306,7 +306,7 @@ sub org_closed_overlap { $after = $_dt_parser->parse_datetime( $end ); $after->add( minutes => 1 ); - while ( my $_a = org_closed_overlap($self, $client, $ou, $after->iso8601, 1 ) ) { + while ( my $_a = new_org_closed_overlap($self, $client, $ou, $after->iso8601, 1 ) ) { $after = $_dt_parser->parse_datetime( clense_ISO8601($_a->{end}) ); } $end = clense_ISO8601($after->iso8601); @@ -324,6 +324,126 @@ sub org_closed_overlap { } __PACKAGE__->register_method( api_name => 'open-ils.storage.actor.org_unit.closed_date.overlap', + api_level => 0, + method => 'new_org_closed_overlap', +); + +sub org_closed_overlap { + my $self = shift; + my $client = shift; + my $ou = shift; + my $date = shift; + my $direction = shift || 0; + my $no_hoo = shift || 0; + + return undef unless ($date && $ou); + + my $t = actor::org_unit::closed_date->table; + my $sql = <<" SQL"; + SELECT * + FROM $t + WHERE ? between close_start and close_end + AND org_unit = ? + ORDER BY close_start ASC, close_end DESC + LIMIT 1 + SQL + + $date = clense_ISO8601($date); + my ($begin, $end) = ($date,$date); + + my $hoo = actor::org_unit::hours_of_operation->retrieve($ou); + + if (my $closure = actor::org_unit::closed_date->db_Main->selectrow_hashref( $sql, {}, $date, $ou )) { + $begin = clense_ISO8601($closure->{close_start}); + $end = clense_ISO8601($closure->{close_end}); + + if ( $direction <= 0 ) { + $before = $_dt_parser->parse_datetime( $begin ); + $before->subtract( minutes => 1 ); + + while ( my $_b = org_closed_overlap($self, $client, $ou, $before->strftime('%FT%T%z'), -1, 1 ) ) { + $before = $_dt_parser->parse_datetime( clense_ISO8601($_b->{start}) ); + } + $begin = clense_ISO8601($before->strftime('%FT%T%z')); + } + + if ( $direction >= 0 ) { + $after = $_dt_parser->parse_datetime( $end ); + $after->add( minutes => 1 ); + + while ( my $_a = org_closed_overlap($self, $client, $ou, $after->strftime('%FT%T%z'), 1, 1 ) ) { + $after = $_dt_parser->parse_datetime( clense_ISO8601($_a->{end}) ); + } + $end = clense_ISO8601($after->strftime('%FT%T%z')); + } + } + + if ( !$no_hoo ) { + if ( $hoo ) { + + if ( $direction <= 0 ) { + my $begin_dow = $_dt_parser->parse_datetime( $begin )->day_of_week_0; + my $begin_open_meth = "dow_".$begin_dow."_open"; + my $begin_close_meth = "dow_".$begin_dow."_close"; + + my $count = 1; + while ($hoo->$begin_open_meth eq '00:00:00' and $hoo->$begin_close_meth eq '00:00:00') { + $begin = clense_ISO8601($_dt_parser->parse_datetime( $begin )->subtract( days => 1)->strftime('%FT%T%z')); + $begin_dow++; + $begin_dow %= 7; + $count++; + last if ($count > 6); + $begin_open_meth = "dow_".$begin_dow."_open"; + $begin_close_meth = "dow_".$begin_dow."_close"; + } + + if (my $closure = actor::org_unit::closed_date->db_Main->selectrow_hashref( $sql, {}, $begin, $ou )) { + $before = $_dt_parser->parse_datetime( $begin ); + $before->subtract( minutes => 1 ); + while ( my $_b = org_closed_overlap($self, $client, $ou, $before->strftime('%FT%T%z'), -1 ) ) { + $before = $_dt_parser->parse_datetime( clense_ISO8601($_b->{start}) ); + } + } + } + + if ( $direction >= 0 ) { + my $end_dow = $_dt_parser->parse_datetime( $end )->day_of_week_0; + my $end_open_meth = "dow_".$end_dow."_open"; + my $end_close_meth = "dow_".$end_dow."_close"; + + $count = 1; + while ($hoo->$end_open_meth eq '00:00:00' and $hoo->$end_close_meth eq '00:00:00') { + $end = clense_ISO8601($_dt_parser->parse_datetime( $end )->add( days => 1)->strftime('%FT%T%z')); + $end_dow++; + $end_dow %= 7; + $count++; + last if ($count > 6); + $end_open_meth = "dow_".$end_dow."_open"; + $end_close_meth = "dow_".$end_dow."_close"; + } + + if (my $closure = actor::org_unit::closed_date->db_Main->selectrow_hashref( $sql, {}, $end, $ou )) { + $after = $_dt_parser->parse_datetime( $end ); + $after->add( minutes => 1 ); + + while ( my $_a = org_closed_overlap($self, $client, $ou, $after->strftime('%FT%T%z'), 1 ) ) { + $after = $_dt_parser->parse_datetime( clense_ISO8601($_a->{end}) ); + } + $end = clense_ISO8601($after->strftime('%FT%T%z')); + } + } + + } + } + + if ($begin eq $date && $end eq $date) { + return undef; + } + + return { start => $begin, end => $end }; +} +__PACKAGE__->register_method( + api_name => 'open-ils.storage.actor.org_unit.closed_date.overlap', api_level => 1, method => 'org_closed_overlap', );