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

(-)a/C4/Circulation.pm (-3 / +62 lines)
Lines 63-68 use Koha::SearchEngine::Indexer; Link Here
63
use Koha::Exceptions::Checkout;
63
use Koha::Exceptions::Checkout;
64
use Koha::Plugins;
64
use Koha::Plugins;
65
use Koha::Recalls;
65
use Koha::Recalls;
66
use Koha::Library::Hours;
66
use Carp qw( carp );
67
use Carp qw( carp );
67
use List::MoreUtils qw( any );
68
use List::MoreUtils qw( any );
68
use Scalar::Util qw( looks_like_number blessed );
69
use Scalar::Util qw( looks_like_number blessed );
Lines 3821-3831 sub CalcDateDue { Link Here
3821
        }
3822
        }
3822
    );
3823
    );
3823
3824
3825
    my $considerlibraryhours = C4::Context->preference('ConsiderLibraryHoursWhenIssuing');
3826
    # starter vars so don't do calculations directly to $datedue
3827
    my $potential_datedue = $datedue->clone;
3828
    my $library_close = $datedue->clone;
3829
    my $dayofweek = $datedue->local_day_of_week - 1;
3830
    my $todayhours = Koha::Library::Hours->find({ branchcode => $branch, day => $dayofweek });
3831
    my @close = undef;
3832
    my $tomorrowhours = Koha::Library::Hours->find({ branchcode => $branch, day => $dayofweek+1 }); # get open hours of next day
3833
    my @open = undef;
3834
    if ( $todayhours->close_time and $tomorrowhours->open_time ) {
3835
        @close = split( ":", $todayhours->close_time );
3836
        $library_close = $library_close->set( hour => $close[0], minute => $close[1] );
3837
        $potential_datedue = $potential_datedue->add( hours => $loanlength->{$length_key} ); # datedue without consideration for open hours
3838
        @open = split( ":", $tomorrowhours->open_time );
3839
    }
3840
3824
    # calculate the datedue as normal
3841
    # calculate the datedue as normal
3825
    if ( $daysmode eq 'Days' )
3842
    if ( $daysmode eq 'Days' )
3826
    {    # ignoring calendar
3843
    {    # ignoring calendar
3827
        if ( $loanlength->{lengthunit} eq 'hours' ) {
3844
        if ( $loanlength->{lengthunit} eq 'hours' ) {
3828
            $datedue->add( hours => $loanlength->{$length_key} );
3845
            if ( $potential_datedue > $library_close and $todayhours->close_time and $tomorrowhours->open_time ) {
3846
                if ( $considerlibraryhours eq 'close' ) {
3847
                    # datedue will be after the library closes on that day
3848
                    # shorten loan period to end when library closes
3849
                    $datedue->set( hour => $close[0], minute => $close[1] );
3850
                } elsif ( $considerlibraryhours eq 'open' ) {
3851
                    # datedue will be after the library closes on that day
3852
                    # extend loan period to when library opens following day
3853
                    $datedue->add( days => 1 )->set( hour => $open[0], minute => $open[1] );
3854
                } else {
3855
                    # ignore library open hours
3856
                    $datedue->add( hours => $loanlength->{$length_key} );
3857
                }
3858
            } else {
3859
                # due time doesn't conflict with library open hours, don't need to check
3860
                $datedue->add( hours => $loanlength->{$length_key} );
3861
            }
3829
        } else {    # days
3862
        } else {    # days
3830
            $datedue->add( days => $loanlength->{$length_key} );
3863
            $datedue->add( days => $loanlength->{$length_key} );
3831
            $datedue->set_hour(23);
3864
            $datedue->set_hour(23);
Lines 3833-3849 sub CalcDateDue { Link Here
3833
        }
3866
        }
3834
    } else {
3867
    } else {
3835
        my $dur;
3868
        my $dur;
3869
        my $sethours;
3836
        if ($loanlength->{lengthunit} eq 'hours') {
3870
        if ($loanlength->{lengthunit} eq 'hours') {
3837
            $dur = DateTime::Duration->new( hours => $loanlength->{$length_key});
3871
            if ( $potential_datedue > $library_close and $todayhours->close_time and $tomorrowhours->open_time ) {
3872
                if ( $considerlibraryhours eq 'close' ) {
3873
                    # datedue will be after the library closes on that day
3874
                    # shorten loan period to end when library closes
3875
                    $dur = $potential_datedue->delta_ms( $library_close );
3876
                    $sethours = $considerlibraryhours;
3877
                } elsif ( $considerlibraryhours eq 'open' ) {
3878
                    # datedue will be after the library closes on that day
3879
                    # extend loan period to when library opens following day
3880
                    my $library_open = $datedue->clone->set( hour => $open[0], minute => $open[1] );
3881
                    $dur = $potential_datedue->delta_ms( $library_open )->add( days => 1 );
3882
                    $sethours = $considerlibraryhours;
3883
                } else {
3884
                    # ignore library open hours
3885
                    $dur = DateTime::Duration->new( hours => $loanlength->{$length_key} );
3886
                }
3887
            } else {
3888
                # due time doesn't conflict with library open hours, don't need to check
3889
                $dur = DateTime::Duration->new( hours => $loanlength->{$length_key} );
3890
            }
3838
        }
3891
        }
3839
        else { # days
3892
        else { # days
3840
            $dur = DateTime::Duration->new( days => $loanlength->{$length_key});
3893
            $dur = DateTime::Duration->new( days => $loanlength->{$length_key} );
3841
        }
3894
        }
3842
        my $calendar = Koha::Calendar->new( branchcode => $branch, days_mode => $daysmode );
3895
        my $calendar = Koha::Calendar->new( branchcode => $branch, days_mode => $daysmode );
3843
        $datedue = $calendar->addDuration( $datedue, $dur, $loanlength->{lengthunit} );
3896
        $datedue = $calendar->addDuration( $datedue, $dur, $loanlength->{lengthunit} );
3844
        if ($loanlength->{lengthunit} eq 'days') {
3897
        if ($loanlength->{lengthunit} eq 'days') {
3845
            $datedue->set_hour(23);
3898
            $datedue->set_hour(23);
3846
            $datedue->set_minute(59);
3899
            $datedue->set_minute(59);
3900
        } else {
3901
            if ( $sethours and $sethours eq 'close' ) {
3902
                $datedue->set( hour => $close[0], minute => $close[1] );
3903
            } elsif ( $sethours and $sethours eq 'open' ) {
3904
                $datedue->set( hour => $open[0], minute => $open[1] );
3905
            }
3847
        }
3906
        }
3848
    }
3907
    }
3849
3908
(-)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 => 19;
5
use Test::More tests => 23;
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 340-344 my $renewed_date = $start_date->clone->add( days => 7 ); Link Here
340
$date = C4::Circulation::CalcDateDue( $start_date, $itemtype, $branchcode, $borrower, 1 );
341
$date = C4::Circulation::CalcDateDue( $start_date, $itemtype, $branchcode, $borrower, 1 );
341
is( $date->ymd, $renewed_date->ymd, 'Renewal period of "" should trigger fallover to issuelength for renewal' );
342
is( $date->ymd, $renewed_date->ymd, 'Renewal period of "" should trigger fallover to issuelength for renewal' );
342
343
344
# Testing hourly loans consider library open hours
345
346
my $library1 = $builder->build( { source => 'Branch' } );
347
Koha::CirculationRules->set_rules(
348
    {
349
        categorycode => $categorycode,
350
        itemtype     => $itemtype,
351
        branchcode   => $library1->{branchcode},
352
        rules        => {
353
            issuelength   => 3, # loan period is 3 hours
354
            lengthunit    => 'hours',
355
        }
356
    }
357
);
358
359
my $open = DateTime->now->subtract( hours => 4 )->hms;
360
my $close = DateTime->now->add( hours => 2 )->hms;
361
my $now = DateTime->now;
362
363
foreach (0..6) {
364
    # library opened 4 hours ago and closes in 2 hours.
365
    Koha::Library::Hour->new({ day => $_, branchcode => $library1->{branchcode}, open_time => $open, close_time => $close })->store;
366
}
367
368
# ignore calendar
369
t::lib::Mocks::mock_preference('useDaysMode', 'Days');
370
t::lib::Mocks::mock_preference('ConsiderLibraryHoursWhenIssuing', 'close');
371
# shorten loan period
372
373
$date = C4::Circulation::CalcDateDue( $now, $itemtype, $library1->{branchcode}, $borrower );
374
my $expected_duetime = DateTime->now->add( hours => 2 );
375
is( $date, $expected_duetime, "Loan period was shortened because ConsiderLibraryHoursWhenIssuing is set to close time" );
376
377
t::lib::Mocks::mock_preference('ConsiderLibraryHoursWhenIssuing', 'open');
378
# extend loan period
379
380
$date = C4::Circulation::CalcDateDue( $now, $itemtype, $library1->{branchcode}, $borrower );
381
$expected_duetime = DateTime->now->add( days => 1 )->subtract( hours => 4 );
382
is( $date, $expected_duetime, "Loan period was extended because ConsiderLibraryHoursWhenIssuing is set to open time" );
383
384
my $holiday_tomorrow = DateTime->now->add( days => 1 );
385
386
# consider calendar
387
my $library1_calendar = C4::Calendar->new( branchcode => $library1->{branchcode} );
388
$library1_calendar->insert_single_holiday(
389
    day             => $holiday_tomorrow->day,
390
    month           => $holiday_tomorrow->month,
391
    year            => $holiday_tomorrow->year,
392
    title           => 'testholiday',
393
    description     => 'testholiday'
394
);
395
Koha::CirculationRules->set_rules(
396
    {
397
        categorycode => $categorycode,
398
        itemtype     => $itemtype,
399
        branchcode   => $library1->{branchcode},
400
        rules        => {
401
            issuelength   => 13, # loan period must cross over into tomorrow
402
            lengthunit    => 'hours',
403
        }
404
    }
405
);
406
407
t::lib::Mocks::mock_preference('useDaysMode', 'Calendar');
408
t::lib::Mocks::mock_preference('ConsiderLibraryHoursWhenIssuing', 'close');
409
# shorten loan period
410
411
$date = C4::Circulation::CalcDateDue( $now, $itemtype, $library1->{branchcode}, $borrower );
412
$expected_duetime = DateTime->now->add( days => 2, hours => 2 );
413
is( $date, $expected_duetime, "Loan period was shortened (but considers the holiday) because ConsiderLibraryHoursWhenIssuing is set to close time" );
414
415
t::lib::Mocks::mock_preference('ConsiderLibraryHoursWhenIssuing', 'open');
416
# extend loan period
417
418
$date = C4::Circulation::CalcDateDue( $now, $itemtype, $library1->{branchcode}, $borrower );
419
$expected_duetime = DateTime->now->add( days => 2 )->subtract( hours => 4 );
420
is( $date, $expected_duetime, "Loan period was extended (but considers the holiday) because ConsiderLibraryHoursWhenIssuing is set to open time" );
421
343
$cache->clear_from_cache($key);
422
$cache->clear_from_cache($key);
344
$schema->storage->txn_rollback;
423
$schema->storage->txn_rollback;
345
- 

Return to bug 6796