[open-ils-commits] r14868 - trunk/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher (miker)
svn at svn.open-ils.org
svn at svn.open-ils.org
Wed Nov 11 13:50:45 EST 2009
Author: miker
Date: 2009-11-11 13:50:41 -0500 (Wed, 11 Nov 2009)
New Revision: 14868
Modified:
trunk/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/actor.pm
Log:
fixing typo in crazy-search (user search); moving to DateTime::SpanSet for time overlap calculation and support "after midnight" closing times
Modified: trunk/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/actor.pm
===================================================================
--- trunk/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/actor.pm 2009-11-11 18:05:59 UTC (rev 14867)
+++ trunk/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/actor.pm 2009-11-11 18:50:41 UTC (rev 14868)
@@ -8,6 +8,8 @@
use DateTime;
use DateTime::Format::ISO8601;
+use DateTime::Set;
+use DateTime::SpanSet;
my $_dt_parser = DateTime::Format::ISO8601->new;
@@ -203,7 +205,59 @@
method => 'calc_proximity',
);
+sub make_hoo_spanset {
+ my $hoo = shift;
+ my $today = shift || DateTime->now;
+ my $tz = OpenSRF::AppSession->create('open-ils.actor')->request(
+ 'open-ils.actor.ou_setting.ancestor_default' => $hoo->id.'' => 'org_unit.timezone'
+ )->gather(1) || DateTime::TimeZone->new( name => 'local' )->name;
+
+ my $current_dow = $today->day_of_week_0;
+
+ my $spanset = DateTime::SpanSet->empty_set;
+ for my $d ( 0 .. 6 ) {
+
+ my $omethod = 'dow_'.$d.'_open';
+ my $cmethod = 'dow_'.$d.'_close';
+
+ my $open = interval_to_seconds($hoo->$omethod());
+ my $close = interval_to_seconds($hoo->$cmethod());
+
+ next if ($open == $close && $open == 0);
+
+ my $dow_offset = ($d - $current_dow) * $one_day;
+ $close += $one_day if ($close <= $open);
+
+ $spanset = $spanset->union(
+ DateTime::Span->new(
+ start => $today->clone->add( seconds => $dow_offset + $open ),
+ end => $today->clone->add( seconds => $dow_offset + $close )
+ )
+ );
+ }
+
+ return $spanset->complement;
+}
+
+sub make_closure_spanset {
+ my $closures = shift;
+
+ my $spanset = DateTime::SpanSet->empty_set;
+ for my $k ( keys %$closures ) {
+ my $c = $$closures{$k};
+
+ $spanset = $spanset->union(
+ DateTime::Span->new(
+ start => $_dt_parser->parse_datetime(clense_ISO8601($c->{close_start})),
+ end => $_dt_parser->parse_datetime(clense_ISO8601($c->{close_end}))
+ )
+ );
+ }
+
+ return $spanset;
+}
+
sub org_closed_overlap {
my $self = shift;
my $client = shift;
@@ -218,105 +272,76 @@
my $sql = <<" SQL";
SELECT *
FROM $t
- WHERE ? between close_start and close_end
+ WHERE 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);
+ my $target_date = $_dt_parser->parse_datetime( $date );
+ my ($begin, $end) = ($target_date, $target_date);
- 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});
+ my $closure_spanset = make_closure_spanset(
+ actor::org_unit::closed_date->db_Main->selectall_hashref( $sql, 'id', {}, $date, $ou )
+ );
+ if ($closure_spanset->intersects( $target_date )) {
+ my $closure_intersection = $closure_spanset->intersection( $target_date );
+ $begin = $closure_intersection->min;
+ $end = $closure_intersection->max;
+
if ( $direction <= 0 ) {
- $before = $_dt_parser->parse_datetime( $begin );
- $before->subtract( minutes => 1 );
+ $begin->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}) );
+ while ( my $_b = org_closed_overlap($self, $client, $ou, $begin->strftime('%FT%T%z'), -1, 1 ) ) {
+ $begin = $_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 );
+ $end->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}) );
+ while ( my $_a = org_closed_overlap($self, $client, $ou, $end->strftime('%FT%T%z'), 1, 1 ) ) {
+ $end = $_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 $begin_hoo = make_hoo_spanset(actor::org_unit::hours_of_operation->retrieve($ou), $begin);
+ my $end_hoo = make_hoo_spanset(actor::org_unit::hours_of_operation->retrieve($ou), $end );
- 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 ( $begin_hoo && $direction <= 0 && $begin_hoo->intersects($begin) ) {
+ my $hoo_intersection = $begin_hoo->intersection( $begin );
+ $begin = $hoo_intersection->min;
+ $begin->subtract( minutes => 1 );
+
+ while ( my $_b = org_closed_overlap($self, $client, $ou, $begin->strftime('%FT%T%z'), -1 ) ) {
+ $begin = $_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 ( $end_hoo && $direction >= 0 && $end_hoo->intersects($end) ) {
+ my $hoo_intersection = $end_hoo->intersection( $end );
+ $end = $hoo_intersection->max;
+ $end->add( minutes => 1 );
- 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'));
- }
- }
+ while ( my $_b = org_closed_overlap($self, $client, $ou, $end->strftime('%FT%T%z'), -1 ) ) {
+ $end = $_dt_parser->parse_datetime( clense_ISO8601($_b->{end}) );
+ }
+ }
+ }
- }
- }
+ if ($begin eq $date && $end eq $date) {
+ return undef;
+ }
- if ($begin eq $date && $end eq $date) {
- return undef;
- }
-
- return { start => $begin, end => $end };
+ return { start => $begin->strftime('%FT%T%z'), end => $end->strftime('%FT%T%z') };
}
__PACKAGE__->register_method(
api_name => 'open-ils.storage.actor.org_unit.closed_date.overlap',
@@ -535,7 +560,7 @@
my @namev;
if (0 && $nv) {
for my $n ( qw/first_given_name second_given_name family_name/ ) {
- push @ns, "LOWER($i) ~ ?";
+ push @ns, "LOWER($n) ~ ?";
push @namev, "^$nv";
}
$name = '(' . join(' OR ', @ns) . ')';
More information about the open-ils-commits
mailing list