View | Details | Raw Unified | Return to bug 6796
Collapse All | Expand All

(-)a/C4/Circulation.pm (-3 / +62 lines)
Lines 61-66 use Koha::Config::SysPref; Link Here
61
use Koha::Checkouts::ReturnClaims;
61
use Koha::Checkouts::ReturnClaims;
62
use Koha::SearchEngine::Indexer;
62
use Koha::SearchEngine::Indexer;
63
use Koha::Exceptions::Checkout;
63
use Koha::Exceptions::Checkout;
64
use Koha::Library::Hours;
64
use Carp qw( carp );
65
use Carp qw( carp );
65
use List::MoreUtils qw( any );
66
use List::MoreUtils qw( any );
66
use Scalar::Util qw( looks_like_number );
67
use Scalar::Util qw( looks_like_number );
Lines 3649-3659 sub CalcDateDue { Link Here
3649
        }
3650
        }
3650
    );
3651
    );
3651
3652
3653
    my $considerlibraryhours = C4::Context->preference('ConsiderLibraryHoursWhenIssuing');
3654
    # starter vars so don't do calculations directly to $datedue
3655
    my $potential_datedue = $datedue->clone;
3656
    my $library_close = $datedue->clone;
3657
    my $dayofweek = $datedue->local_day_of_week - 1;
3658
    my $todayhours = Koha::Library::Hours->find({ branchcode => $branch, day => $dayofweek });
3659
    my @close = undef;
3660
    my $tomorrowhours = Koha::Library::Hours->find({ branchcode => $branch, day => $dayofweek+1 }); # get open hours of next day
3661
    my @open = undef;
3662
    if ( $todayhours->close_time and $tomorrowhours->open_time ) {
3663
        @close = split( ":", $todayhours->close_time );
3664
        $library_close = $library_close->set( hour => $close[0], minute => $close[1] );
3665
        $potential_datedue = $potential_datedue->add( hours => $loanlength->{$length_key} ); # datedue without consideration for open hours
3666
        @open = split( ":", $tomorrowhours->open_time );
3667
    }
3668
3652
    # calculate the datedue as normal
3669
    # calculate the datedue as normal
3653
    if ( $daysmode eq 'Days' )
3670
    if ( $daysmode eq 'Days' )
3654
    {    # ignoring calendar
3671
    {    # ignoring calendar
3655
        if ( $loanlength->{lengthunit} eq 'hours' ) {
3672
        if ( $loanlength->{lengthunit} eq 'hours' ) {
3656
            $datedue->add( hours => $loanlength->{$length_key} );
3673
            if ( $potential_datedue > $library_close and $todayhours->close_time and $tomorrowhours->open_time ) {
3674
                if ( $considerlibraryhours eq 'close' ) {
3675
                    # datedue will be after the library closes on that day
3676
                    # shorten loan period to end when library closes
3677
                    $datedue->set( hour => $close[0], minute => $close[1] );
3678
                } elsif ( $considerlibraryhours eq 'open' ) {
3679
                    # datedue will be after the library closes on that day
3680
                    # extend loan period to when library opens following day
3681
                    $datedue->add( days => 1 )->set( hour => $open[0], minute => $open[1] );
3682
                } else {
3683
                    # ignore library open hours
3684
                    $datedue->add( hours => $loanlength->{$length_key} );
3685
                }
3686
            } else {
3687
                # due time doesn't conflict with library open hours, don't need to check
3688
                $datedue->add( hours => $loanlength->{$length_key} );
3689
            }
3657
        } else {    # days
3690
        } else {    # days
3658
            $datedue->add( days => $loanlength->{$length_key} );
3691
            $datedue->add( days => $loanlength->{$length_key} );
3659
            $datedue->set_hour(23);
3692
            $datedue->set_hour(23);
Lines 3661-3677 sub CalcDateDue { Link Here
3661
        }
3694
        }
3662
    } else {
3695
    } else {
3663
        my $dur;
3696
        my $dur;
3697
        my $sethours;
3664
        if ($loanlength->{lengthunit} eq 'hours') {
3698
        if ($loanlength->{lengthunit} eq 'hours') {
3665
            $dur = DateTime::Duration->new( hours => $loanlength->{$length_key});
3699
            if ( $potential_datedue > $library_close and $todayhours->close_time and $tomorrowhours->open_time ) {
3700
                if ( $considerlibraryhours eq 'close' ) {
3701
                    # datedue will be after the library closes on that day
3702
                    # shorten loan period to end when library closes
3703
                    $dur = $potential_datedue->delta_ms( $library_close );
3704
                    $sethours = $considerlibraryhours;
3705
                } elsif ( $considerlibraryhours eq 'open' ) {
3706
                    # datedue will be after the library closes on that day
3707
                    # extend loan period to when library opens following day
3708
                    my $library_open = $datedue->clone->set( hour => $open[0], minute => $open[1] );
3709
                    $dur = $potential_datedue->delta_ms( $library_open )->add( days => 1 );
3710
                    $sethours = $considerlibraryhours;
3711
                } else {
3712
                    # ignore library open hours
3713
                    $dur = DateTime::Duration->new( hours => $loanlength->{$length_key} );
3714
                }
3715
            } else {
3716
                # due time doesn't conflict with library open hours, don't need to check
3717
                $dur = DateTime::Duration->new( hours => $loanlength->{$length_key} );
3718
            }
3666
        }
3719
        }
3667
        else { # days
3720
        else { # days
3668
            $dur = DateTime::Duration->new( days => $loanlength->{$length_key});
3721
            $dur = DateTime::Duration->new( days => $loanlength->{$length_key} );
3669
        }
3722
        }
3670
        my $calendar = Koha::Calendar->new( branchcode => $branch, days_mode => $daysmode );
3723
        my $calendar = Koha::Calendar->new( branchcode => $branch, days_mode => $daysmode );
3671
        $datedue = $calendar->addDuration( $datedue, $dur, $loanlength->{lengthunit} );
3724
        $datedue = $calendar->addDuration( $datedue, $dur, $loanlength->{lengthunit} );
3672
        if ($loanlength->{lengthunit} eq 'days') {
3725
        if ($loanlength->{lengthunit} eq 'days') {
3673
            $datedue->set_hour(23);
3726
            $datedue->set_hour(23);
3674
            $datedue->set_minute(59);
3727
            $datedue->set_minute(59);
3728
        } else {
3729
            if ( $sethours and $sethours eq 'close' ) {
3730
                $datedue->set( hour => $close[0], minute => $close[1] );
3731
            } elsif ( $sethours and $sethours eq 'open' ) {
3732
                $datedue->set( hour => $open[0], minute => $open[1] );
3733
            }
3675
        }
3734
        }
3676
    }
3735
    }
3677
3736
(-)a/t/db_dependent/Circulation/CalcDateDue.t (-3 / +81 lines)
Lines 2-15 Link Here
2
2
3
use Modern::Perl;
3
use Modern::Perl;
4
4
5
use Test::More tests => 17;
5
use Test::More tests => 21;
6
use Test::MockModule;
6
use Test::MockModule;
7
use DBI;
7
use DBI;
8
use DateTime;
8
use DateTime;
9
use t::lib::Mocks;
9
use t::lib::Mocks;
10
use t::lib::TestBuilder;
10
use t::lib::TestBuilder;
11
use C4::Calendar qw( new insert_single_holiday delete_holiday insert_week_day_holiday );
11
use C4::Calendar qw( new insert_single_holiday delete_holiday insert_week_day_holiday );
12
12
use Koha::DateUtils qw( dt_from_string );
13
use Koha::Library::Hour;
13
use Koha::CirculationRules;
14
use Koha::CirculationRules;
14
15
15
use_ok('C4::Circulation', qw( CalcDateDue ));
16
use_ok('C4::Circulation', qw( CalcDateDue ));
Lines 303-307 $calendar->delete_holiday( Link Here
303
    weekday => 6
304
    weekday => 6
304
);
305
);
305
306
307
# Testing hourly loans consider library open hours
308
309
my $library1 = $builder->build( { source => 'Branch' } );
310
Koha::CirculationRules->set_rules(
311
    {
312
        categorycode => $categorycode,
313
        itemtype     => $itemtype,
314
        branchcode   => $library1->{branchcode},
315
        rules        => {
316
            issuelength   => 3, # loan period is 3 hours
317
            lengthunit    => 'hours',
318
        }
319
    }
320
);
321
322
my $open = DateTime->now->subtract( hours => 4 )->hms;
323
my $close = DateTime->now->add( hours => 2 )->hms;
324
my $now = DateTime->now;
325
326
foreach (0..6) {
327
    # library opened 4 hours ago and closes in 2 hours.
328
    Koha::Library::Hour->new({ day => $_, branchcode => $library1->{branchcode}, open_time => $open, close_time => $close })->store;
329
}
330
331
# ignore calendar
332
t::lib::Mocks::mock_preference('useDaysMode', 'Days');
333
t::lib::Mocks::mock_preference('ConsiderLibraryHoursWhenIssuing', 'close');
334
# shorten loan period
335
336
$date = C4::Circulation::CalcDateDue( $now, $itemtype, $library1->{branchcode}, $borrower );
337
my $expected_duetime = DateTime->now->add( hours => 2 );
338
is( $date, $expected_duetime, "Loan period was shortened because ConsiderLibraryHoursWhenIssuing is set to close time" );
339
340
t::lib::Mocks::mock_preference('ConsiderLibraryHoursWhenIssuing', 'open');
341
# extend loan period
342
343
$date = C4::Circulation::CalcDateDue( $now, $itemtype, $library1->{branchcode}, $borrower );
344
$expected_duetime = DateTime->now->add( days => 1 )->subtract( hours => 4 );
345
is( $date, $expected_duetime, "Loan period was extended because ConsiderLibraryHoursWhenIssuing is set to open time" );
346
347
my $holiday_tomorrow = DateTime->now->add( days => 1 );
348
349
# consider calendar
350
my $library1_calendar = C4::Calendar->new( branchcode => $library1->{branchcode} );
351
$library1_calendar->insert_single_holiday(
352
    day             => $holiday_tomorrow->day,
353
    month           => $holiday_tomorrow->month,
354
    year            => $holiday_tomorrow->year,
355
    title           => 'testholiday',
356
    description     => 'testholiday'
357
);
358
Koha::CirculationRules->set_rules(
359
    {
360
        categorycode => $categorycode,
361
        itemtype     => $itemtype,
362
        branchcode   => $library1->{branchcode},
363
        rules        => {
364
            issuelength   => 13, # loan period must cross over into tomorrow
365
            lengthunit    => 'hours',
366
        }
367
    }
368
);
369
370
t::lib::Mocks::mock_preference('useDaysMode', 'Calendar');
371
t::lib::Mocks::mock_preference('ConsiderLibraryHoursWhenIssuing', 'close');
372
# shorten loan period
373
374
$date = C4::Circulation::CalcDateDue( $now, $itemtype, $library1->{branchcode}, $borrower );
375
$expected_duetime = DateTime->now->add( days => 2, hours => 2 );
376
is( $date, $expected_duetime, "Loan period was shortened (but considers the holiday) because ConsiderLibraryHoursWhenIssuing is set to close time" );
377
378
t::lib::Mocks::mock_preference('ConsiderLibraryHoursWhenIssuing', 'open');
379
# extend loan period
380
381
$date = C4::Circulation::CalcDateDue( $now, $itemtype, $library1->{branchcode}, $borrower );
382
$expected_duetime = DateTime->now->add( days => 2 )->subtract( hours => 4 );
383
is( $date, $expected_duetime, "Loan period was extended (but considers the holiday) because ConsiderLibraryHoursWhenIssuing is set to open time" );
384
306
$cache->clear_from_cache($key);
385
$cache->clear_from_cache($key);
307
$schema->storage->txn_rollback;
386
$schema->storage->txn_rollback;
308
- 

Return to bug 6796