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

(-)a/C4/Circulation.pm (-11 / +17 lines)
Lines 4158-4172 sub CalcDateDue { Link Here
4158
        ;    # get open hours of next day
4158
        ;    # get open hours of next day
4159
4159
4160
    # Defend against missing library hours definitions
4160
    # Defend against missing library hours definitions
4161
    if ( !$todayhours || !$tomorrowhours ) { $considerlibraryhours = 'ignore' }
4161
    # For 'close' mode, we only need today's hours
4162
    # For 'open' mode, we need both today's and tomorrow's hours
4163
    if ( !$todayhours ) {
4164
        $considerlibraryhours = 'ignore';
4165
    } elsif ( $considerlibraryhours eq 'open' && !$tomorrowhours ) {
4166
        $considerlibraryhours = 'ignore';
4167
    }
4162
4168
4163
    my @open = undef;
4169
    my @open = undef;
4164
    if ( $considerlibraryhours ne 'ignore' and $todayhours->close_time and $tomorrowhours->open_time ) {
4170
    if ( $considerlibraryhours ne 'ignore' and $todayhours and $todayhours->close_time ) {
4165
        @close             = split( ":", $todayhours->close_time );
4171
        @close             = split( ":", $todayhours->close_time );
4166
        $library_close     = $library_close->set( hour => $close[0], minute => $close[1] );
4172
        $library_close     = $library_close->set( hour => $close[0], minute => $close[1] );
4167
        $potential_datedue = $potential_datedue->add( hours => $loanlength->{$length_key} )
4173
        $potential_datedue = $potential_datedue->add( hours => $loanlength->{$length_key} )
4168
            ;    # datedue without consideration for open hours
4174
            ;    # datedue without consideration for open hours
4169
        @open = split( ":", $tomorrowhours->open_time );
4175
        if ( $considerlibraryhours eq 'open' and $tomorrowhours and $tomorrowhours->open_time ) {
4176
            @open = split( ":", $tomorrowhours->open_time );
4177
        }
4170
    }
4178
    }
4171
4179
4172
    # calculate the datedue as normal
4180
    # calculate the datedue as normal
Lines 4174-4195 sub CalcDateDue { Link Here
4174
        if ( $loanlength->{lengthunit} eq 'hours' ) {
4182
        if ( $loanlength->{lengthunit} eq 'hours' ) {
4175
            if (    $considerlibraryhours ne 'ignore'
4183
            if (    $considerlibraryhours ne 'ignore'
4176
                and $potential_datedue > $library_close
4184
                and $potential_datedue > $library_close
4177
                and $todayhours->close_time
4185
                and $todayhours->close_time )
4178
                and $tomorrowhours->open_time )
4179
            {
4186
            {
4180
                if ( $considerlibraryhours eq 'close' ) {
4187
                if ( $considerlibraryhours eq 'close' ) {
4181
4188
4182
                    # datedue will be after the library closes on that day
4189
                    # datedue will be after the library closes on that day
4183
                    # shorten loan period to end when library closes
4190
                    # shorten loan period to end when library closes
4184
                    $datedue->set( hour => $close[0], minute => $close[1] );
4191
                    $datedue->set( hour => $close[0], minute => $close[1] );
4185
                } elsif ( $considerlibraryhours eq 'open' ) {
4192
                } elsif ( $considerlibraryhours eq 'open' and $tomorrowhours and $tomorrowhours->open_time ) {
4186
4193
4187
                    # datedue will be after the library closes on that day
4194
                    # datedue will be after the library closes on that day
4188
                    # extend loan period to when library opens following day
4195
                    # extend loan period to when library opens following day
4189
                    $datedue->add( days => 1 )->set( hour => $open[0], minute => $open[1] );
4196
                    $datedue->add( days => 1 )->set( hour => $open[0], minute => $open[1] );
4190
                } else {
4197
                } else {
4191
4198
4192
                    # ignore library open hours
4199
                    # ignore library open hours or can't extend to tomorrow (no tomorrow hours)
4193
                    $datedue->add( hours => $loanlength->{$length_key} );
4200
                    $datedue->add( hours => $loanlength->{$length_key} );
4194
                }
4201
                }
4195
            } else {
4202
            } else {
Lines 4207-4221 sub CalcDateDue { Link Here
4207
        if ( $loanlength->{lengthunit} eq 'hours' ) {
4214
        if ( $loanlength->{lengthunit} eq 'hours' ) {
4208
            if (    $considerlibraryhours ne 'ignore'
4215
            if (    $considerlibraryhours ne 'ignore'
4209
                and $potential_datedue > $library_close
4216
                and $potential_datedue > $library_close
4210
                and $todayhours->close_time
4217
                and $todayhours->close_time )
4211
                and $tomorrowhours->open_time )
4212
            {
4218
            {
4213
                if ( $considerlibraryhours eq 'close' ) {
4219
                if ( $considerlibraryhours eq 'close' ) {
4214
4220
4215
                    # datedue will be after the library closes on that day
4221
                    # datedue will be after the library closes on that day
4216
                    # shorten loan period to end when library closes by hardcoding due time
4222
                    # shorten loan period to end when library closes by hardcoding due time
4217
                    $datedue->set( hour => $close[0], minute => $close[1] );
4223
                    $datedue->set( hour => $close[0], minute => $close[1] );
4218
                } elsif ( $considerlibraryhours eq 'open' ) {
4224
                } elsif ( $considerlibraryhours eq 'open' and $tomorrowhours and $tomorrowhours->open_time ) {
4219
4225
4220
                    # datedue will be after the library closes on that day
4226
                    # datedue will be after the library closes on that day
4221
                    # extend loan period to when library opens following day by hardcoding due time for next open day
4227
                    # extend loan period to when library opens following day by hardcoding due time for next open day
Lines 4223-4229 sub CalcDateDue { Link Here
4223
                    $datedue->set( hour => $open[0], minute => $open[1] );
4229
                    $datedue->set( hour => $open[0], minute => $open[1] );
4224
                } else {
4230
                } else {
4225
4231
4226
                    # ignore library open hours
4232
                    # ignore library open hours or can't extend to tomorrow (no tomorrow hours)
4227
                    $dur = DateTime::Duration->new( hours => $loanlength->{$length_key} );
4233
                    $dur = DateTime::Duration->new( hours => $loanlength->{$length_key} );
4228
                }
4234
                }
4229
            } else {
4235
            } else {
(-)a/t/db_dependent/Circulation/CalcDateDue.t (-2 / +61 lines)
Lines 3-9 Link Here
3
use Modern::Perl;
3
use Modern::Perl;
4
4
5
use Test::NoWarnings;
5
use Test::NoWarnings;
6
use Test::More tests => 24;
6
use Test::More tests => 27;
7
use Test::MockModule;
7
use Test::MockModule;
8
use DBI;
8
use DBI;
9
use DateTime;
9
use DateTime;
Lines 492-496 is( Link Here
492
    "Loan period was extended (but considers the holiday) because ConsiderLibraryHoursInCirculation is set to open time"
492
    "Loan period was extended (but considers the holiday) because ConsiderLibraryHoursInCirculation is set to open time"
493
);
493
);
494
494
495
# Bug 38940 - Test that ConsiderLibraryHoursInCirculation='close' works when tomorrow has no hours
496
# This tests the scenario where a library is closed the next day (e.g., weekend)
497
# but should still shorten loans to today's closing time
498
499
my $library2 = $builder->build( { source => 'Branch' } );
500
Koha::CirculationRules->set_rules(
501
    {
502
        categorycode => $borrower->categorycode,
503
        itemtype     => $itemtype,
504
        branchcode   => $library2->{branchcode},
505
        rules        => {
506
            issuelength => 3,         # loan period is 3 hours
507
            lengthunit  => 'hours',
508
            daysmode    => '',
509
        }
510
    }
511
);
512
513
# Set up hours for Friday (day 5): open 10:00, close 16:00
514
# Saturday (day 6) will have NO hours (null), simulating a weekend
515
my $friday_open  = DateTime->new( year => 2023, month => 5, day => 5, hour => 10 )->hms;
516
my $friday_close = DateTime->new( year => 2023, month => 5, day => 5, hour => 16 )->hms;
517
my $friday_now   = DateTime->new( year => 2023, month => 5, day => 5, hour => 14 );        # 2PM on Friday
518
519
# Only set hours for Friday (day 5), leaving Saturday (day 6) with null hours
520
Koha::Library::Hour->new(
521
    { day => 5, library_id => $library2->{branchcode}, open_time => $friday_open, close_time => $friday_close } )
522
    ->store;
523
524
t::lib::Mocks::mock_preference( 'useDaysMode',                       'Days' );
525
t::lib::Mocks::mock_preference( 'ConsiderLibraryHoursInCirculation', 'close' );
526
527
# Test with 'close' mode - should shorten to 4PM today even though tomorrow has no hours
528
$date             = C4::Circulation::CalcDateDue( $friday_now, $itemtype, $library2->{branchcode}, $borrower );
529
$expected_duetime = $friday_now->clone->set( hour => 16, minute => 0 );
530
is(
531
    $date, $expected_duetime,
532
    "Bug 38940: Loan period shortened to closing time when next day has null hours (ConsiderLibraryHoursInCirculation='close')"
533
);
534
535
# Test with 'open' mode - should fall back to regular 3-hour loan since tomorrow has no hours
536
t::lib::Mocks::mock_preference( 'ConsiderLibraryHoursInCirculation', 'open' );
537
$date             = C4::Circulation::CalcDateDue( $friday_now, $itemtype, $library2->{branchcode}, $borrower );
538
$expected_duetime = $friday_now->clone->add( hours => 3 );
539
is(
540
    $date, $expected_duetime,
541
    "Bug 38940: Loan period not extended when next day has null hours (ConsiderLibraryHoursInCirculation='open' falls back to standard loan)"
542
);
543
544
# Test the same scenario with Calendar daysmode
545
t::lib::Mocks::mock_preference( 'useDaysMode',                       'Calendar' );
546
t::lib::Mocks::mock_preference( 'ConsiderLibraryHoursInCirculation', 'close' );
547
548
$date             = C4::Circulation::CalcDateDue( $friday_now, $itemtype, $library2->{branchcode}, $borrower );
549
$expected_duetime = $friday_now->clone->set( hour => 16, minute => 0 );
550
is(
551
    $date, $expected_duetime,
552
    "Bug 38940: Loan period shortened with Calendar mode when next day has null hours (ConsiderLibraryHoursInCirculation='close')"
553
);
554
495
$cache->clear_from_cache($key);
555
$cache->clear_from_cache($key);
496
$schema->storage->txn_rollback;
556
$schema->storage->txn_rollback;
497
- 

Return to bug 38940