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

(-)a/C4/Calendar.pm (-1 / +61 lines)
Lines 17-29 package C4::Calendar; Link Here
17
17
18
use strict;
18
use strict;
19
use warnings;
19
use warnings;
20
use vars qw($VERSION @EXPORT);
20
use vars qw($VERSION @ISA @EXPORT_OK @EXPORT);
21
21
22
use Carp;
22
use Carp;
23
use Date::Calc qw( Date_to_Days Today);
23
use Date::Calc qw( Date_to_Days Today);
24
24
25
use C4::Context;
25
use C4::Context;
26
26
27
BEGIN {
28
    $VERSION   = 3.07.00.049;
29
    @ISA       = qw(Exporter);
30
    @EXPORT_OK = qw(setOpeningHours getOpeningHours);
31
}
32
27
use constant ISO_DATE_FORMAT => "%04d-%02d-%02d";
33
use constant ISO_DATE_FORMAT => "%04d-%02d-%02d";
28
=head1 NAME
34
=head1 NAME
29
35
Lines 722-727 sub daysBetween { Link Here
722
    return($count);
728
    return($count);
723
}
729
}
724
730
731
sub setOpeningHours {
732
    my ($branchcode, $weekcode, $openhour, $closehour) = @_;
733
734
    my $dbh = C4::Context->dbh;
735
    my $sth = $dbh->prepare("SELECT * FROM openinghours WHERE branchcode = ? AND weekcode = ?");
736
    $sth->execute($branchcode, $weekcode);
737
738
    if ( not $sth->fetchrow_hashref ) {
739
        my $sth2 = $dbh->prepare('INSERT INTO openinghours (branchcode, weekcode, openhour, closehour) VALUES(?,?,?,?)');
740
741
        $sth2->execute( $branchcode, $weekcode, $openhour, $closehour );
742
    }
743
    else {
744
    my $sth3 = $dbh->prepare('UPDATE openinghours set openhour = ?, closehour = ? WHERE branchcode = ? AND weekcode = ? ');
745
746
    $sth3->execute( $openhour, $closehour, $branchcode, $weekcode );
747
    }
748
}
749
750
sub getOpeningHours {
751
    my ($branchcode) = @_;
752
    my $dbh = C4::Context->dbh;
753
    my $query = "SELECT * FROM openinghours ";
754
    $query .= "WHERE branchcode = ?" if(defined $branchcode);
755
    my $sth = $dbh->prepare($query);
756
757
    my %results;
758
759
    if($branchcode){
760
        $sth->execute($branchcode);
761
        while ( my $hours = $sth->fetchrow_hashref ) {
762
            $results{ $hours->{'weekcode'} } = $hours;
763
        }
764
    }
765
    else{
766
        $sth->execute();
767
        my @tmp;
768
        while ( my $row = $sth->fetchrow_hashref ) {
769
            #add a few precalculated fields
770
            my $t1 = DateTime::Format::DateParse->parse_datetime( $row->{openhour});
771
            my $t2 = DateTime::Format::DateParse->parse_datetime( $row->{closehour});
772
            $row->{hashopen} = {hour => $t1->hour(), minute => $t1->minute(), second => $t1->second()};
773
            $row->{hashclose} = {hour => $t2->hour(), minute => $t2->minute(), second => $t2->second() };
774
            $row->{totalminutes} = $t1->delta_ms($t2)->delta_minutes();
775
776
            #build the hash
777
            $results{ $row->{'branchcode'} } ||= {};
778
            $results{ $row->{'branchcode'} }->{$row->{'weekcode'}} = $row;
779
       }
780
    }
781
782
    return \%results;
783
}
784
725
1;
785
1;
726
786
727
__END__
787
__END__
(-)a/C4/Circulation.pm (-7 / +30 lines)
Lines 33-38 use C4::Dates qw(format_date); Link Here
33
use C4::Accounts;
33
use C4::Accounts;
34
use C4::ItemCirculationAlertPreference;
34
use C4::ItemCirculationAlertPreference;
35
use C4::Message;
35
use C4::Message;
36
use C4::Calendar qw(getOpeningHours);
36
use C4::Debug;
37
use C4::Debug;
37
use C4::Branch; # GetBranches
38
use C4::Branch; # GetBranches
38
use C4::Log; # logaction
39
use C4::Log; # logaction
Lines 91-96 BEGIN { Link Here
91
		&AnonymiseIssueHistory
92
		&AnonymiseIssueHistory
92
        &CheckIfIssuedToPatron
93
        &CheckIfIssuedToPatron
93
        &IsItemIssued
94
        &IsItemIssued
95
        &CalcDateDue
94
	);
96
	);
95
97
96
	# subs to deal with returns
98
	# subs to deal with returns
Lines 120-125 BEGIN { Link Here
120
      &DeleteOfflineOperation
122
      &DeleteOfflineOperation
121
      &ProcessOfflineOperation
123
      &ProcessOfflineOperation
122
    );
124
    );
125
123
}
126
}
124
127
125
=head1 NAME
128
=head1 NAME
Lines 1729-1735 sub AddReturn { Link Here
1729
        return (0, { BadBarcode => $barcode }); # no barcode means no item or borrower.  bail out.
1732
        return (0, { BadBarcode => $barcode }); # no barcode means no item or borrower.  bail out.
1730
    }
1733
    }
1731
    my $issue  = GetItemIssue($itemnumber);
1734
    my $issue  = GetItemIssue($itemnumber);
1732
#   warn Dumper($iteminformation);
1735
1733
    if ($issue and $issue->{borrowernumber}) {
1736
    if ($issue and $issue->{borrowernumber}) {
1734
        $borrower = C4::Members::GetMemberDetails($issue->{borrowernumber})
1737
        $borrower = C4::Members::GetMemberDetails($issue->{borrowernumber})
1735
            or die "Data inconsistency: barcode $barcode (itemnumber:$itemnumber) claims to be issued to non-existant borrowernumber '$issue->{borrowernumber}'\n"
1738
            or die "Data inconsistency: barcode $barcode (itemnumber:$itemnumber) claims to be issued to non-existant borrowernumber '$issue->{borrowernumber}'\n"
Lines 3228-3233 C<$borrower> = Borrower object Link Here
3228
C<$isrenewal> = Boolean: is true if we want to calculate the date due for a renewal. Else is false.
3231
C<$isrenewal> = Boolean: is true if we want to calculate the date due for a renewal. Else is false.
3229
3232
3230
=cut
3233
=cut
3234
sub CapDateDue{
3235
    my ( $calcDueDate, $loanlength, $branch) = @_;
3236
3237
    # for hourly loans, we will limit the due date to close time
3238
    return $calcDueDate unless ($loanlength->{lengthunit} eq 'hours');
3239
3240
#    my $now = DateTime->now( time_zone => C4::Context->tz() );
3241
    my $branchHours = getOpeningHours();
3242
3243
    my $close = $calcDueDate->clone()->truncate( to => 'days');
3244
    $close->set($branchHours->{$branch}->{$calcDueDate->local_day_of_week()-1}->{hashclose});
3245
3246
    if (DateTime->compare($calcDueDate, $close) > 0){ # we want the document back at close time
3247
        return $close;
3248
    }
3249
3250
    return $calcDueDate;
3251
}
3231
3252
3232
sub CalcDateDue {
3253
sub CalcDateDue {
3233
    my ( $startdate, $itemtype, $branch, $borrower, $isrenewal ) = @_;
3254
    my ( $startdate, $itemtype, $branch, $borrower, $isrenewal ) = @_;
Lines 3255-3267 sub CalcDateDue { Link Here
3255
          ->truncate( to => 'minute' );
3276
          ->truncate( to => 'minute' );
3256
    }
3277
    }
3257
3278
3258
3279
    my $calendar = Koha::Calendar->new( branchcode => $branch );
3259
    # calculate the datedue as normal
3280
    # calculate the datedue as normal
3260
    if ( C4::Context->preference('useDaysMode') eq 'Days' )
3281
    if ( C4::Context->preference('useDaysMode') eq 'Days' )
3261
    {    # ignoring calendar
3282
    {    # ignoring calendar
3262
        if ( $loanlength->{lengthunit} eq 'hours' ) {
3283
        if ( $loanlength->{lengthunit} eq 'hours' ) {
3263
            $datedue->add( hours => $loanlength->{$length_key} );
3284
            if($loanlength->{issuelength}  == 24){
3264
        } else {    # days
3285
                $datedue = $calendar->addDate( $datedue, 1);
3286
            } else {
3287
                $datedue->add( hours => $loanlength->{issuelength} );
3288
            }
3289
        }else {    # days
3265
            $datedue->add( days => $loanlength->{$length_key} );
3290
            $datedue->add( days => $loanlength->{$length_key} );
3266
            $datedue->set_hour(23);
3291
            $datedue->set_hour(23);
3267
            $datedue->set_minute(59);
3292
            $datedue->set_minute(59);
Lines 3274-3280 sub CalcDateDue { Link Here
3274
        else { # days
3299
        else { # days
3275
            $dur = DateTime::Duration->new( days => $loanlength->{$length_key});
3300
            $dur = DateTime::Duration->new( days => $loanlength->{$length_key});
3276
        }
3301
        }
3277
        my $calendar = Koha::Calendar->new( branchcode => $branch );
3278
        $datedue = $calendar->addDate( $datedue, $dur, $loanlength->{lengthunit} );
3302
        $datedue = $calendar->addDate( $datedue, $dur, $loanlength->{lengthunit} );
3279
        if ($loanlength->{lengthunit} eq 'days') {
3303
        if ($loanlength->{lengthunit} eq 'days') {
3280
            $datedue->set_hour(23);
3304
            $datedue->set_hour(23);
Lines 3311-3317 sub CalcDateDue { Link Here
3311
        }
3335
        }
3312
    }
3336
    }
3313
3337
3314
    return $datedue;
3338
    return CapDateDue($datedue, $loanlength, $branch);
3315
}
3339
}
3316
3340
3317
3341
Lines 3761-3764 __END__ Link Here
3761
Koha Development Team <http://koha-community.org/>
3785
Koha Development Team <http://koha-community.org/>
3762
3786
3763
=cut
3787
=cut
3764
(-)a/C4/Overdues.pm (-10 / +21 lines)
Lines 41-46 BEGIN { Link Here
41
	# subs to rename (and maybe merge some...)
41
	# subs to rename (and maybe merge some...)
42
	push @EXPORT, qw(
42
	push @EXPORT, qw(
43
        &CalcFine
43
        &CalcFine
44
        &_get_chargeable_units
44
        &Getoverdues
45
        &Getoverdues
45
        &checkoverdues
46
        &checkoverdues
46
        &NumberNotifyId
47
        &NumberNotifyId
Lines 110-117 sub Getoverdues { Link Here
110
    if ( C4::Context->preference('item-level_itypes') ) {
111
    if ( C4::Context->preference('item-level_itypes') ) {
111
        $statement = "
112
        $statement = "
112
   SELECT issues.*, items.itype as itemtype, items.homebranch, items.barcode
113
   SELECT issues.*, items.itype as itemtype, items.homebranch, items.barcode
113
     FROM issues 
114
     FROM issues
114
LEFT JOIN items       USING (itemnumber)
115
LEFT JOIN items       USING (itemnumber)
116
join issuingrules on issuingrules.itemtype = items.itype
115
    WHERE date_due < NOW()
117
    WHERE date_due < NOW()
116
";
118
";
117
    } else {
119
    } else {
Lines 135-140 LEFT JOIN biblioitems USING (biblioitemnumber) Link Here
135
        $statement .= ' AND ( TO_DAYS( NOW() )-TO_DAYS( date_due ) ) < ? ';
137
        $statement .= ' AND ( TO_DAYS( NOW() )-TO_DAYS( date_due ) ) < ? ';
136
        push @bind_parameters, $params->{'maximumdays'};
138
        push @bind_parameters, $params->{'maximumdays'};
137
    }
139
    }
140
141
    if($params->{'shortrun'}){
142
        $statement .= " and issuingrules.lengthunit in ('hours')  " ;
143
    }
144
138
    $statement .= 'ORDER BY borrowernumber';
145
    $statement .= 'ORDER BY borrowernumber';
139
    my $sth = $dbh->prepare( $statement );
146
    my $sth = $dbh->prepare( $statement );
140
    $sth->execute( @bind_parameters );
147
    $sth->execute( @bind_parameters );
Lines 240-246 or "Final Notice". But CalcFine never defined any value. Link Here
240
=cut
247
=cut
241
248
242
sub CalcFine {
249
sub CalcFine {
243
    my ( $item, $bortype, $branchcode, $due_dt, $end_date  ) = @_;
250
    my ( $item, $bortype, $branchcode, $due_dt, $end_date, $openingHours  ) = @_;
244
    my $start_date = $due_dt->clone();
251
    my $start_date = $due_dt->clone();
245
    # get issuingrules (fines part will be used)
252
    # get issuingrules (fines part will be used)
246
    my $itemtype = $item->{itemtype} || $item->{itype};
253
    my $itemtype = $item->{itemtype} || $item->{itype};
Lines 248-254 sub CalcFine { Link Here
248
    my $fine_unit = $data->{lengthunit};
255
    my $fine_unit = $data->{lengthunit};
249
    $fine_unit ||= 'days';
256
    $fine_unit ||= 'days';
250
257
251
    my $chargeable_units = _get_chargeable_units($fine_unit, $start_date, $end_date, $branchcode);
258
    my $chargeable_units = _get_chargeable_units($fine_unit, $start_date, $end_date, $branchcode, $openingHours);
252
    my $units_minus_grace = $chargeable_units - $data->{firstremind};
259
    my $units_minus_grace = $chargeable_units - $data->{firstremind};
253
    my $amount = 0;
260
    my $amount = 0;
254
    if ($data->{'chargeperiod'}  && ($units_minus_grace > 0)  ) {
261
    if ($data->{'chargeperiod'}  && ($units_minus_grace > 0)  ) {
Lines 282-306 C<$branchcode> is the branch whose calendar to use for finding holidays. Link Here
282
=cut
289
=cut
283
290
284
sub _get_chargeable_units {
291
sub _get_chargeable_units {
285
    my ($unit, $dt1, $dt2, $branchcode) = @_;
292
    my ($unit, $dt1, $dt2, $branchcode, $openingHours) = @_;
286
    my $charge_units = 0;
293
    my $charge_units = 0;
287
    my $charge_duration;
294
    my $charge_duration;
288
    if ($unit eq 'hours') {
295
    if ($unit eq 'hours') {
289
        if(C4::Context->preference('finesCalendar') eq 'noFinesWhenClosed') {
296
        if(C4::Context->preference('finesCalendar') eq 'noFinesWhenClosed') {
290
            my $calendar = Koha::Calendar->new( branchcode => $branchcode );
297
            if (!defined $openingHours->{$branchcode}{'Calendar'}){
291
            $charge_duration = $calendar->hours_between( $dt1, $dt2 );
298
                $openingHours->{$branchcode}{'Calendar'} = Koha::Calendar->new( branchcode => $branchcode );
299
            }
300
            $charge_duration = $openingHours->{$branchcode}{'Calendar'}->hours_between( $dt1, $dt2, $openingHours->{$branchcode} );
292
        } else {
301
        } else {
293
            $charge_duration = $dt2->delta_ms( $dt1 );
302
            $charge_duration = $dt2->delta_ms( $dt1 );
294
        }
303
        }
295
        if($charge_duration->in_units('hours') == 0 && $charge_duration->in_units('seconds') > 0){
304
        if($charge_duration->in_units($unit) == 0 && $charge_duration->in_units('seconds') > 0){
296
            return 1;
305
            return 1;
297
        }
306
        }
298
        return $charge_duration->in_units('hours');
307
        return $charge_duration->in_units($unit);
299
    }
308
    }
300
    else { # days
309
    else { # days
301
        if(C4::Context->preference('finesCalendar') eq 'noFinesWhenClosed') {
310
        if(C4::Context->preference('finesCalendar') eq 'noFinesWhenClosed') {
302
            my $calendar = Koha::Calendar->new( branchcode => $branchcode );
311
            if (!defined $openingHours->{$branchcode}{'Calendar'}){
303
            $charge_duration = $calendar->days_between( $dt1, $dt2 );
312
                $openingHours->{$branchcode}{'Calendar'} = Koha::Calendar->new( branchcode => $branchcode );
313
            }
314
            $charge_duration = $openingHours->{$branchcode}{'Calendar'}->days_between( $dt1, $dt2, $openingHours->{$branchcode} );
304
        } else {
315
        } else {
305
            $charge_duration = $dt2->delta_days( $dt1 );
316
            $charge_duration = $dt2->delta_days( $dt1 );
306
        }
317
        }
(-)a/Koha/Calendar.pm (-26 / +58 lines)
Lines 271-277 sub days_between { Link Here
271
    my $self     = shift;
271
    my $self     = shift;
272
    my $start_dt = shift;
272
    my $start_dt = shift;
273
    my $end_dt   = shift;
273
    my $end_dt   = shift;
274
274
    my $branchHours = shift;
275
    if ( $start_dt->compare($end_dt) > 0 ) {
275
    if ( $start_dt->compare($end_dt) > 0 ) {
276
        # swap dates
276
        # swap dates
277
        my $int_dt = $end_dt;
277
        my $int_dt = $end_dt;
Lines 279-325 sub days_between { Link Here
279
        $start_dt = $int_dt;
279
        $start_dt = $int_dt;
280
    }
280
    }
281
281
282
283
    # start and end should not be closed days
284
    my $days = $start_dt->delta_days($end_dt)->delta_days;
282
    my $days = $start_dt->delta_days($end_dt)->delta_days;
285
    for (my $dt = $start_dt->clone();
283
    # start and end should not be closed days
286
        $dt <= $end_dt;
284
    while ($start_dt <= $end_dt) {
287
        $dt->add(days => 1)
285
        if (defined $branchHours->{holidays}{$start_dt->ymd()}) {
288
    ) {
286
            $days-- if $branchHours->{holidays}{$start_dt->ymd()};
289
        if ($self->is_holiday($dt)) {
287
        } else {
290
            $days--;
288
            $branchHours->{holidays}{$start_dt->ymd()} = $self->is_holiday($start_dt);
289
            $days-- if $branchHours->{holidays}{$start_dt->ymd()};
291
        }
290
        }
291
        $start_dt->add(days => 1);
292
    }
292
    }
293
    return DateTime::Duration->new( days => $days );
293
    return DateTime::Duration->new( days => $days );
294
294
295
}
295
}
296
296
297
sub hours_between {
297
sub hours_between {
298
    my ($self, $start_date, $end_date) = @_;
298
    my ($self, $start_date, $end_date, $branchHours) = @_;
299
299
    my $start_dt = $start_date->clone();
300
    my $start_dt = $start_date->clone();
300
    my $end_dt = $end_date->clone();
301
    my $end_dt = $end_date->clone();
301
    my $duration = $end_dt->delta_ms($start_dt);
302
302
    $start_dt->truncate( to => 'day' );
303
    $start_dt->truncate( to => 'day' );
303
    $end_dt->truncate( to => 'day' );
304
    $end_dt->truncate( to => 'day' );
304
    # NB this is a kludge in that it assumes all days are 24 hours
305
305
    # However for hourly loans the logic should be expanded to
306
    if (defined $branchHours->{0}){ # We were given the branch's opening hours.
306
    # take into account open/close times then it would be a duration
307
        my $totalMinutes = 0;
307
    # of library open hours
308
        for (my $dt = $start_dt->clone(); $dt <= $end_dt; $dt->add(days => 1)) {
308
    my $skipped_days = 0;
309
            # hash to keep track of holidays
309
    for (my $dt = $start_dt->clone();
310
            if (defined $branchHours->{holidays}{$dt->ymd()}) {
310
        $dt <= $end_dt;
311
                next if $branchHours->{holidays}{$dt->ymd()};
311
        $dt->add(days => 1)
312
            } else {
312
    ) {
313
                $branchHours->{holidays}{$dt->ymd()} = $self->is_holiday($dt);
313
        if ($self->is_holiday($dt)) {
314
                next if ($self->is_holiday($dt));
314
            ++$skipped_days;
315
            }
316
317
            if(DateTime->compare($dt,$start_dt) == 0){ # from location till close time
318
            #create a timestamp for today's close time using the current day object with the branchHours's hours.
319
                my $close = $dt->clone()->set($branchHours->{$dt->local_day_of_week()-1}->{hashclose});
320
321
                if(DateTime->compare($end_date, $close) < 0){ # we are still the same day, before closing time
322
                    $totalMinutes += $start_date->delta_ms($end_date)->delta_minutes();
323
                } elsif(DateTime->compare($start_date, $close) < 0) { # we started (issue) before closing hour
324
                    $totalMinutes += $start_date->delta_ms($close)->delta_minutes();
325
                }
326
            }
327
            elsif(DateTime->compare($dt, $end_dt) == 0){  # from open time till now
328
                my $open = $dt->clone()->set($branchHours->{$dt->local_day_of_week()-1}->{hashopen});
329
                if(DateTime->compare($end_date, $open) > 0) { # we end (return issue) after opening hour
330
                    $totalMinutes += $end_date->delta_ms($open)->delta_minutes();
331
                }
332
            }
333
            else{
334
                $totalMinutes += $branchHours->{$dt->local_day_of_week()- 1}->{totalminutes};
335
            }
315
        }
336
        }
337
338
        return DateTime::Duration->new( minutes => $totalMinutes);
316
    }
339
    }
317
    if ($skipped_days) {
340
    else{
318
        $duration->subtract_duration(DateTime::Duration->new( hours => 24 * $skipped_days));
341
        my $duration = $end_dt->delta_ms($start_dt);
342
        my $skipped_days = 0;
343
        while ($start_dt <= $end_dt){
344
            if ($self->is_holiday($start_dt)) {
345
                ++$skipped_days;
346
            }
347
            $start_dt->add(days => 1);
348
        }
349
        if ($skipped_days) {
350
            $duration->subtract_duration(DateTime::Duration->new( hours => 24 * $skipped_days));
351
        }
352
        return $duration;
319
    }
353
    }
320
354
321
    return $duration;
322
323
}
355
}
324
356
325
sub set_daysmode {
357
sub set_daysmode {
(-)a/installer/data/mysql/updatedatabase.pl (+34 lines)
Lines 8560-8565 if ( CheckVersion($DBversion) ) { Link Here
8560
    SetVersion($DBversion);
8560
    SetVersion($DBversion);
8561
}
8561
}
8562
8562
8563
$DBversion ="XXX";
8564
if( CheckVersion($DBversion) ){
8565
    $dbh->do(q{
8566
        CREATE TABLE IF NOT EXISTS openinghours (
8567
          branchcode varchar(10) NOT NULL,
8568
          weekcode int(2) NOT NULL,
8569
          openhour time NOT NULL,
8570
          closehour time NOT NULL,
8571
          PRIMARY KEY (branchcode,weekcode)
8572
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
8573
        });
8574
    $dbh->do(q{
8575
        ALTER TABLE openinghours
8576
            ADD CONSTRAINT openinghours_ibfk_1
8577
            FOREIGN KEY (branchcode) REFERENCES
8578
            branches(branchcode);
8579
        });
8580
8581
    my $sth = $dbh->prepare("SELECT branchcode FROM branches");
8582
    $sth->execute;
8583
    my @branches;
8584
    my $weekcode;
8585
    while (@branches = $sth->fetchrow_array()){
8586
        for ($weekcode = 0; $weekcode <= 6; $weekcode++) {
8587
        my $count = $dbh->selectrow_array('SELECT count(*) FROM openinghours WHERE branchcode=? and weekcode=?',undef, $branches[0], $weekcode);
8588
        if ($count==0){
8589
            $dbh->do('INSERT INTO openinghours (branchcode, weekcode, openhour, closehour) VALUES (?, ?, ? ,?)', undef, $branches[0], $weekcode, '09:00:00', '17:00:00') or die $dbh->errstr;
8590
        }
8591
       }
8592
    }
8593
    print "Calendar opening hours set.\n";
8594
    SetVersion($DBversion);
8595
}
8596
8563
=head1 FUNCTIONS
8597
=head1 FUNCTIONS
8564
8598
8565
=head2 TableExists($table)
8599
=head2 TableExists($table)
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/holidays.tt (-1 / +142 lines)
Lines 6-11 Link Here
6
[% INCLUDE 'datatables.inc' %]
6
[% INCLUDE 'datatables.inc' %]
7
<script type="text/javascript">
7
<script type="text/javascript">
8
//<![CDATA[
8
//<![CDATA[
9
10
    var MSG_HOURS_INCOHERENT = _("Opening hours could not be greater than the closing hours");
11
12
    [% IF (dateformat == 'metric') %]dt_add_type_uk_date();[% END %]
9
    var weekdays = new Array(_("Sundays"),_("Mondays"),_("Tuesdays"),_("Wednesdays"),_("Thursdays"),_("Fridays"),_("Saturdays"));
13
    var weekdays = new Array(_("Sundays"),_("Mondays"),_("Tuesdays"),_("Wednesdays"),_("Thursdays"),_("Fridays"),_("Saturdays"));
10
14
11
    /* Creates all the structures to deal with all different kinds of holidays */
15
    /* Creates all the structures to deal with all different kinds of holidays */
Lines 36-41 Link Here
36
        formObject.submit();
40
        formObject.submit();
37
    }
41
    }
38
42
43
    function checkschedule() {
44
    var verify = 0;
45
    for (var i=0; i<7 ; i++) {
46
         var tabopenhour = document.getElementById('openhour_' + i);
47
         var selectValueoh = tabopenhour.options[tabopenhour.selectedIndex].value;
48
49
         var tabopenmin = document.getElementById('openmin_' + i);
50
         var selectValueom = tabopenmin.options[tabopenmin.selectedIndex].value;
51
52
         var tabclosehour = document.getElementById('closehour_' + i);
53
         var selectValuech = tabclosehour.options[tabclosehour.selectedIndex].value;
54
55
         var tabclosemin = document.getElementById('closemin_' + i);
56
         var selectValuecm = tabclosemin.options[tabclosemin.selectedIndex].value;
57
58
         if (selectValueoh == selectValuech) {
59
         if (selectValueom > selectValuecm) {
60
              alert(MSG_HOURS_INCOHERENT);
61
              verify = 1;
62
              break;
63
             }
64
         } else if (selectValueoh > selectValuech) {
65
         alert(MSG_HOURS_INCOHERENT);
66
         verify = 1;
67
         break;
68
         }
69
    }
70
71
    if (verify != 0) {
72
         return false;
73
    }
74
    return true;
75
    }
39
    // This function shows the "Show Holiday" panel //
76
    // This function shows the "Show Holiday" panel //
40
    function showHoliday (exceptionPosibility, dayName, day, month, year, weekDay, title, description, holidayType) {
77
    function showHoliday (exceptionPosibility, dayName, day, month, year, weekDay, title, description, holidayType) {
41
        $("#newHoliday").slideUp("fast");
78
        $("#newHoliday").slideUp("fast");
Lines 447-453 td.repeatableyearly a.ui-state-default { background: #FFCC66 none; color : Bl Link Here
447
  </tr>
484
  </tr>
448
  [% END %] 
485
  [% END %] 
449
</tbody>
486
</tbody>
450
</table>
487
451
[% END %]
488
[% END %]
452
489
453
[% IF ( WEEK_DAYS_LOOP ) %]
490
[% IF ( WEEK_DAYS_LOOP ) %]
Lines 523-528 td.repeatableyearly a.ui-state-default { background: #FFCC66 none; color : Bl Link Here
523
</tbody>
560
</tbody>
524
</table>
561
</table>
525
[% END %]
562
[% END %]
563
564
<h3>Opening hours</h3>
565
<form name="formhour" method="post" action="/cgi-bin/koha/tools/holidays.pl" onSubmit="return checkschedule()">
566
<table>
567
<thead>
568
<tr>
569
  <th class="repeatableweekly">Day of week</th>
570
  <th class="repeatableweekly">Opening hours</th>
571
  <th class="repeatableweekly">Closing hours</th>
572
</tr>
573
</thead>
574
<tbody>
575
  [% FOR day IN tabdays %]
576
  <tr>
577
    <td>[% IF ( day == 0 ) %]Sunday[% END %]
578
        [% IF ( day == 1 ) %]Monday[% END %]
579
        [% IF ( day == 2 ) %]Tuesday[% END %]
580
        [% IF ( day == 3 ) %]Wednesday[% END %]
581
        [% IF ( day == 4 ) %]Thursday[% END %]
582
        [% IF ( day == 5 ) %]Friday[% END %]
583
        [% IF ( day == 6 ) %]Saturday[% END %]
584
    </td>
585
    <td>
586
    <select id="openhour_[% day %]" name="openhour_[% day %]">
587
        [% FOR hour IN hours %]
588
                [% flag1 = 0 %]
589
        [% FOREACH tabschedul IN tabschedule %]
590
          [% IF  (day == tabschedul.dayb ) %]
591
            [% IF (hour == tabschedul.openhourb)  %]
592
                           <option value="[% tabschedul.openhourb %]" selected="selected">[% hour %]</option>
593
              [% flag1 = 1 %]
594
              [% END %]
595
          [% END %]
596
        [% END %]
597
598
                [% IF (flag1 == 0) %]
599
                    <option value="[% hour %]">[% hour %]</option>
600
        [% END %]
601
        [% END %]
602
    </select>h
603
    <select id="openmin_[% day %]" name="openmin_[% day %]">
604
        [% FOR minute IN minutes %]
605
                [% flag2 = 0 %]
606
        [% FOREACH tabschedul IN tabschedule %]
607
          [% IF (day == tabschedul.dayb ) %]
608
            [% IF (minute == tabschedul.openminb)  %]
609
                          <option value="[% tabschedul.openminb %]" selected="selected">[% minute %]</option>
610
              [% flag2 = 1 %]
611
              [% END %]
612
          [% END %]
613
        [% END %]
614
615
                [% IF (flag2 == 0) %]
616
                  <option value="[% minute %]">[% minute %]</option>
617
        [% END %]
618
        [% END %]
619
    </select>min
620
    </td>
621
    <td>
622
    <select id="closehour_[% day %]" name="closehour_[% day %]">
623
        [% FOR hour IN hours %]
624
                [% flag3 = 0 %]
625
        [% FOREACH tabschedul IN tabschedule %]
626
          [% IF (day == tabschedul.dayb ) %]
627
            [% IF (hour == tabschedul.closehourb) %]
628
                          <option value="[% tabschedul.closehourb %]" selected="selected">[% hour %]</option>
629
              [% flag3 = 1 %]
630
              [% END %]
631
          [% END %]
632
        [% END %]
633
634
        [% IF (flag3 == 0) %]
635
                  <option value="[% hour %]">[% hour %]</option>
636
        [% END %]
637
        [% END %]
638
    </select>h
639
    <select id="closemin_[% day %]" name="closemin_[% day %]">
640
        [% FOR minute IN minutes %]
641
                [% flag4 = 0 %]
642
        [% FOREACH tabschedul IN tabschedule %]
643
          [% IF (day == tabschedul.dayb ) %]
644
            [% IF (minute == tabschedul.closeminb) %]
645
                           <option value="[% tabschedul.closeminb %]" selected="selected">[% minute %]</option>
646
              [% flag4 = 1 %]
647
              [% END %]
648
          [% END %]
649
        [% END %]
650
651
        [% IF (flag4 == 0) %]
652
                  <option value="[% minute %]">[% minute %]</option>
653
        [% END %]
654
        [% END %]
655
    </select>min
656
    <input type="hidden" name="confirm" value="1" />
657
    <input type="hidden" name="weekcode_[% day %]" value="[% day %]" />
658
    <input type="hidden" name="branch" value="[% branch %]" />
659
    </td>
660
  </tr>
661
  [% END %]
662
  <tr><td colspan=3 align="center"><input type="submit" name="submit" value="Save" /></td></tr>
663
</tbody>
664
</table>
665
</form>
666
526
</div>
667
</div>
527
</div>
668
</div>
528
</div>
669
</div>
(-)a/misc/cronjobs/fines.pl (-6 / +11 lines)
Lines 38-54 use File::Spec; Link Here
38
38
39
use Koha::Calendar;
39
use Koha::Calendar;
40
use Koha::DateUtils;
40
use Koha::DateUtils;
41
use C4::Calendar qw(getOpeningHours);
41
42
42
my $help;
43
my $help;
43
my $verbose;
44
my $verbose;
44
my $output_dir;
45
my $output_dir;
45
my $log;
46
my $log;
47
my $shortrun;
46
48
47
GetOptions(
49
GetOptions(
48
    'h|help'    => \$help,
50
    'h|help'    => \$help,
49
    'v|verbose' => \$verbose,
51
    'v|verbose' => \$verbose,
50
    'l|log'     => \$log,
52
    'l|log'     => \$log,
51
    'o|out:s'   => \$output_dir,
53
    'o|out:s'   => \$output_dir,
54
    's|short'   => \$shortrun,
52
);
55
);
53
my $usage = << 'ENDUSAGE';
56
my $usage = << 'ENDUSAGE';
54
57
Lines 62-67 This script has the following parameters : Link Here
62
    -l --log: log the output to a file (optional if the -o parameter is given)
65
    -l --log: log the output to a file (optional if the -o parameter is given)
63
    -o --out:  ouput directory for logs (defaults to env or /tmp if !exist)
66
    -o --out:  ouput directory for logs (defaults to env or /tmp if !exist)
64
    -v --verbose
67
    -v --verbose
68
    -s --short: only verifies the short duration borrowing (hourly)
65
69
66
ENDUSAGE
70
ENDUSAGE
67
71
Lines 86-91 if ($log or $output_dir) { Link Here
86
    $filename = get_filename($output_dir);
90
    $filename = get_filename($output_dir);
87
}
91
}
88
92
93
my $openingHours = getOpeningHours();
94
89
my $fh;
95
my $fh;
90
if ($filename) {
96
if ($filename) {
91
    open $fh, '>>', $filename or croak "Cannot write file $filename: $!";
97
    open $fh, '>>', $filename or croak "Cannot write file $filename: $!";
Lines 93-103 if ($filename) { Link Here
93
    print {$fh} "\n";
99
    print {$fh} "\n";
94
}
100
}
95
my $counted = 0;
101
my $counted = 0;
96
my $overdues = Getoverdues();
102
my $overdues = Getoverdues( {shortrun => $shortrun});
103
use Data::Dumper;
104
97
for my $overdue ( @{$overdues} ) {
105
for my $overdue ( @{$overdues} ) {
98
    if ( !defined $overdue->{borrowernumber} ) {
106
    if ( !defined $overdue->{borrowernumber} ) {
99
        carp
107
        carp "ERROR in Getoverdues : issues.borrowernumber IS NULL.  Repair 'issues' table now!  Skipping record.\n";
100
"ERROR in Getoverdues : issues.borrowernumber IS NULL.  Repair 'issues' table now!  Skipping record.\n";
101
        next;
108
        next;
102
    }
109
    }
103
    my $borrower = BorType( $overdue->{borrowernumber} );
110
    my $borrower = BorType( $overdue->{borrowernumber} );
Lines 117-125 for my $overdue ( @{$overdues} ) { Link Here
117
    }
124
    }
118
    ++$counted;
125
    ++$counted;
119
126
120
    my ( $amount, $type, $unitcounttotal ) =
127
    my ( $amount, $type, $unitcounttotal ) = CalcFine( $overdue, $borrower->{categorycode}, $branchcode, $datedue, $today, $openingHours );
121
      CalcFine( $overdue, $borrower->{categorycode},
122
        $branchcode, $datedue, $today );
123
    $type ||= q{};
128
    $type ||= q{};
124
129
125
    # Don't update the fine if today is a holiday.
130
    # Don't update the fine if today is a holiday.
(-)a/t/Calendar1.t (+333 lines)
Line 0 Link Here
1
#!/usr/bin/env perl
2
3
use strict;
4
use warnings;
5
use Data::Dumper;
6
use DateTime;
7
use DateTime::Duration;
8
use Test::More tests => 13;
9
use Test::MockModule;
10
use DBD::Mock;
11
use Koha::DateUtils;
12
use C4::Calendar qw(getOpeningHours);
13
use C4::Circulation qw(CalcDateDue);
14
use C4::Overdues qw(_get_chargeable_units);
15
16
BEGIN {
17
    die "DBD::Mock v$DBD::Mock::VERSION is too old. This test requires v1.45 or higher.", 33
18
    unless $DBD::Mock::VERSION >= 1.45;
19
20
    use_ok('Koha::Calendar');
21
    use_ok('C4::Calendar');
22
    use_ok('C4::Circulation');
23
    use_ok('C4::Overdues');
24
}
25
26
my $module_context = new Test::MockModule('C4::Context');
27
$module_context->mock(
28
    '_new_dbh',
29
    sub {
30
        my $dbh = DBI->connect( 'DBI:Mock:', '', '' )
31
          || die "Cannot create handle: $DBI::errstr\n";
32
        return $dbh;
33
    }
34
);
35
36
# Initialize the global $dbh variable
37
my $dbh = C4::Context->dbh();
38
39
{ #C4::Calendar
40
    my $sessionCal = DBD::Mock::Session->new('sessionCal' => (
41
        { #Opening hours by branch
42
            statement => "SELECT * FROM openinghours WHERE branchcode = ?",
43
            bound_params => ['BIB'],
44
            results => [
45
                            ['branchcode', 'weekcode', 'openhour', 'closehour'],
46
                            ['BIB', 0, '09:00:00', '17:00:00'],
47
                            ['BIB', 1, '09:00:00', '17:00:00'],
48
                            ['BIB', 2, '09:00:00', '17:00:00'],
49
                            ['BIB', 3, '09:00:00', '17:00:00'],
50
                            ['BIB', 4, '09:00:00', '17:00:00'],
51
                            ['BIB', 5, '09:00:00', '17:00:00'],
52
                            ['BIB', 6, '09:00:00', '17:00:00']
53
                       ]
54
        }
55
    ));
56
57
    $dbh->{ mock_session } = $sessionCal;
58
59
    print "\nTesting C4::Calendar\n";
60
    can_ok('C4::Calendar', ('getOpeningHours'));
61
    can_ok('C4::Calendar', ('setOpeningHours'));
62
    getOpeningHours('BIB');
63
}
64
65
print "\nTesting C4::Circulation\n";
66
{ #C4::Circulation : Calendar Mode
67
    my $sessionCircCal = DBD::Mock::Session->new('sessionCircCal' => (
68
        # Mock queries for test 7
69
        {
70
           statement => qr/\s*SELECT issuelength, lengthunit, renewalperiod/,
71
           results  => [
72
                            [ 'issuelength', 'lengthunit', 'renewalperiod' ],
73
                            [ 5, 'hours' , 0 ]
74
                        ]
75
        },
76
        {
77
            statement => 'SELECT weekday FROM repeatable_holidays WHERE branchcode = ? AND weekday IS NOT NULL',
78
            results => DBD::Mock->NULL_RESULTSET
79
        },
80
        {
81
            statement => 'SELECT day, month FROM repeatable_holidays WHERE branchcode = ? AND weekday IS NULL',
82
            results => [
83
                            ['day', 'month'],
84
                            [24,6]
85
                        ]
86
        },
87
        {
88
            statement => 'SELECT day, month, year FROM special_holidays WHERE branchcode = ? AND isexception = 1',
89
            results => DBD::Mock->NULL_RESULTSET
90
        },
91
        {
92
            statement => 'SELECT day, month, year FROM special_holidays WHERE branchcode = ? AND isexception = 0',
93
            results => DBD::Mock->NULL_RESULTSET
94
        },
95
        { #GetIssuingRules called in GetHardDueDate
96
            statement => qr/select \* from issuingrules/,
97
            results => [
98
                            ['hardduedate', 'hardduedatecompare'],
99
                            [undef,-1]
100
                        ]
101
        },
102
        { #Opening hours
103
            statement => 'SELECT * FROM openinghours ',
104
            results => [
105
                            ['branchcode', 'weekcode', 'openhour', 'closehour'],
106
                            ['BIB', 0, '09:00:00', '17:00:00'],
107
                            ['BIB', 1, '09:00:00', '17:00:00'],
108
                            ['BIB', 2, '09:00:00', '17:00:00'],
109
                            ['BIB', 3, '09:00:00', '17:00:00'],
110
                            ['BIB', 4, '09:00:00', '17:00:00'],
111
                            ['BIB', 5, '09:00:00', '17:00:00'],
112
                            ['BIB', 6, '09:00:00', '17:00:00']
113
                        ]
114
        },
115
        #   Mock Queries for test 8
116
        {
117
           statement => qr/\s*SELECT issuelength, lengthunit, renewalperiod/,
118
            results  => [
119
                            [ 'issuelength', 'lengthunit', 'renewalperiod' ],
120
                            [ 1, 'days' , 0 ]
121
                        ]
122
        },
123
        {
124
            statement => 'SELECT weekday FROM repeatable_holidays WHERE branchcode = ? AND weekday IS NOT NULL',
125
            results => DBD::Mock->NULL_RESULTSET
126
        },
127
        {
128
            statement => 'SELECT day, month FROM repeatable_holidays WHERE branchcode = ? AND weekday IS NULL',
129
            results => [
130
                            ['day', 'month'],
131
                            [24,6]
132
                        ]
133
        },
134
        { #GetIssuingRules called in GetHardDueDate
135
            statement => qr/select \* from issuingrules/,
136
            results => [
137
                            ['hardduedate', 'hardduedatecompare'],
138
                            [undef,-1]
139
                        ]
140
        },
141
        # Mock queries for test 9
142
        {
143
           statement => qr/\s*SELECT issuelength, lengthunit, renewalperiod/,
144
            results  => [
145
                            [ 'issuelength', 'lengthunit', 'renewalperiod' ],
146
                            [ 5, 'days' , 0 ]
147
                        ]
148
        },
149
        {
150
            statement => 'SELECT weekday FROM repeatable_holidays WHERE branchcode = ? AND weekday IS NOT NULL',
151
            results => DBD::Mock->NULL_RESULTSET
152
        },
153
        {
154
            statement => 'SELECT day, month FROM repeatable_holidays WHERE branchcode = ? AND weekday IS NULL',
155
            results => [
156
                            ['day', 'month'],
157
                            [24,6]
158
                        ]
159
        },
160
        { #GetIssuingRules called in GetHardDueDate
161
            statement => qr/select \* from issuingrules/,
162
            results => [
163
                            ['hardduedate', 'hardduedatecompare'],
164
                            [undef,-1]
165
                        ]
166
        }
167
    ));
168
    $dbh->{ mock_session } = $sessionCircCal;
169
170
    $module_context->mock('preference',sub {return 'Calendar';});
171
    print "  useDaysMode set to 'Calendar'\n";
172
173
    #7 Testing 5 hours loan
174
    is(CalcDateDue(dt_from_string('2014-06-23T14:00:00', 'iso'), 0, 'BIB',{categorycode => 0, dateexpiry => '2020'}, 0), dt_from_string('2014-06-23T17:00:00', 'iso'), "Testing hourly loans. Due at close time.");
175
    #8 Testing single day loan
176
    is(CalcDateDue(dt_from_string('2014-06-23T12:00:00', 'iso'), 0, 'BIB',{categorycode => 0, dateexpiry => '2020'}, 0), dt_from_string('2014-06-25T23:59:00', 'iso'), "Testing single day loan due the day after the holiday.");
177
    #9 Testing 5 days loan
178
    is(CalcDateDue(dt_from_string('2014-06-23T12:00:00', 'iso'), 0, 'BIB',{categorycode => 0, dateexpiry => '2020'}, 0), dt_from_string('2014-06-29T23:59:00', 'iso'), "Testing 5 days loan. Loan period is extended by 1 because of the holiday.");
179
180
    #C4::Circulation : DateDue Mode
181
182
   my $sessionCircDate = DBD::Mock::Session->new('sessionCircDate' => (
183
        # Mock queries for test 10
184
        {
185
           statement => qr/\s*SELECT issuelength, lengthunit, renewalperiod/,
186
           results  => [
187
                            [ 'issuelength', 'lengthunit', 'renewalperiod' ],
188
                            [ 5, 'hours' , 0 ]
189
                        ]
190
        },
191
        {
192
            statement => 'SELECT weekday FROM repeatable_holidays WHERE branchcode = ? AND weekday IS NOT NULL',
193
            results => DBD::Mock->NULL_RESULTSET
194
        },
195
        {
196
            statement => 'SELECT day, month FROM repeatable_holidays WHERE branchcode = ? AND weekday IS NULL',
197
            results => [
198
                            ['day', 'month'],
199
                            [24,6]
200
                        ]
201
        },
202
        { #GetIssuingRules called in GetHardDueDate
203
            statement => qr/select \* from issuingrules/,
204
            results => [
205
                            ['hardduedate', 'hardduedatecompare'],
206
                            [undef,-1]
207
                        ]
208
        },
209
        { #Opening hours
210
            statement => 'SELECT * FROM openinghours ',
211
            results => [
212
                            ['branchcode', 'weekcode', 'openhour', 'closehour'],
213
                            ['BIB', 0, '09:00:00', '17:00:00'],
214
                            ['BIB', 1, '09:00:00', '17:00:00'],
215
                            ['BIB', 2, '09:00:00', '17:00:00'],
216
                            ['BIB', 3, '09:00:00', '17:00:00'],
217
                            ['BIB', 4, '09:00:00', '17:00:00'],
218
                            ['BIB', 5, '09:00:00', '17:00:00'],
219
                            ['BIB', 6, '09:00:00', '17:00:00']
220
                        ]
221
        },
222
        #   Mock Queries for test 11
223
        {
224
           statement => qr/\s*SELECT issuelength, lengthunit, renewalperiod/,
225
            results  => [
226
                            [ 'issuelength', 'lengthunit', 'renewalperiod' ],
227
                            [ 24, 'hours' , 0 ]
228
                        ]
229
        },
230
        {
231
            statement => 'SELECT weekday FROM repeatable_holidays WHERE branchcode = ? AND weekday IS NOT NULL',
232
            results => DBD::Mock->NULL_RESULTSET
233
        },
234
        {
235
            statement => 'SELECT day, month FROM repeatable_holidays WHERE branchcode = ? AND weekday IS NULL',
236
            results => [
237
                            ['day', 'month'],
238
                            [24,6]
239
                        ]
240
        },
241
        { #GetIssuingRules called in GetHardDueDate
242
            statement => qr/select \* from issuingrules/,
243
            results => [
244
                            ['hardduedate', 'hardduedatecompare'],
245
                            [undef,-1]
246
                        ]
247
        },
248
        { #Opening hours
249
            statement => 'SELECT * FROM openinghours ',
250
            results => [
251
                            ['branchcode', 'weekcode', 'openhour', 'closehour'],
252
                            ['BIB', 0, '09:00:00', '17:00:00'],
253
                            ['BIB', 1, '09:00:00', '17:00:00'],
254
                            ['BIB', 2, '09:00:00', '17:00:00'],
255
                            ['BIB', 3, '09:00:00', '17:00:00'],
256
                            ['BIB', 4, '09:00:00', '17:00:00'],
257
                            ['BIB', 5, '09:00:00', '17:00:00'],
258
                            ['BIB', 6, '09:00:00', '17:00:00']
259
                        ]
260
        },
261
        # Mock queries for test 12
262
        {
263
           statement => qr/\s*SELECT issuelength, lengthunit, renewalperiod/,
264
            results  => [
265
                            [ 'issuelength', 'lengthunit', 'renewalperiod' ],
266
                            [ 5, 'days' , 0 ]
267
                        ]
268
        },
269
        {
270
            statement => 'SELECT weekday FROM repeatable_holidays WHERE branchcode = ? AND weekday IS NOT NULL',
271
            results => DBD::Mock->NULL_RESULTSET
272
        },
273
        {
274
            statement => 'SELECT day, month FROM repeatable_holidays WHERE branchcode = ? AND weekday IS NULL',
275
            results => [
276
                            ['day', 'month'],
277
                            [24,6]
278
                       ]
279
        },
280
        { #GetIssuingRules called in GetHardDueDate
281
            statement => qr/select \* from issuingrules/,
282
            results => [
283
                            ['hardduedate', 'hardduedatecompare'],
284
                            [undef,-1]
285
                        ]
286
        }
287
    ));
288
    $module_context->mock('preference',sub {return 'DateDue';});
289
    print "  useDaysMode set to 'DateDue'\n";
290
291
    $dbh->{ mock_session } = $sessionCircDate;
292
293
    #10 Testing 5 hours loan
294
    is(CalcDateDue(dt_from_string('2014-06-23T14:00:00', 'iso'), 0, 'BIB',{categorycode => 0, dateexpiry => '2020'}, 0), dt_from_string('2014-06-23T17:00:00', 'iso'), "Testing hourly loans. Due at close time.");
295
    #11 Testing single day loan
296
    is(CalcDateDue(dt_from_string('2014-06-23T12:00:00', 'iso'), 0, 'BIB',{categorycode => 0, dateexpiry => '2020'}, 0), dt_from_string('2014-06-25T10:00:00', 'iso'), "Testing single day loan due the day after the holiday.");
297
    #12 Testing 5 days loan
298
    is(CalcDateDue(dt_from_string('2014-06-23T12:00:00', 'iso'), 0, 'BIB',{categorycode => 0, dateexpiry => '2020'}, 0), dt_from_string('2014-06-28T23:59:00', 'iso'), "Testing 5 days loan. Unaffected by the single day holiday.");
299
}
300
301
{ #C4::Overdues
302
    print "\nTesting C4::Overdues\n";
303
    $module_context->mock('preference',sub {return 'noFinesWhenClosed';});
304
    print "  finesCalendar syspref set to 'noFinesWhenClosed'\n";
305
    my $sessionOver = DBD::Mock::Session->new('sessionOver' =>(
306
        { #Opening hours
307
            statement => 'SELECT * FROM openinghours ',
308
            results => [
309
                            ['branchcode', 'weekcode', 'openhour', 'closehour'],
310
                            ['BIB', 0, '09:00:00', '17:00:00'],
311
                            ['BIB', 1, '09:00:00', '17:00:00'],
312
                            ['BIB', 2, '09:00:00', '17:00:00'],
313
                            ['BIB', 3, '09:00:00', '17:00:00'],
314
                            ['BIB', 4, '09:00:00', '17:00:00'],
315
                            ['BIB', 5, '09:00:00', '17:00:00'],
316
                            ['BIB', 6, '09:00:00', '17:00:00']
317
                        ]
318
        },
319
        {
320
            statement => 'SELECT weekday FROM repeatable_holidays WHERE branchcode = ? AND weekday IS NOT NULL',
321
            results => DBD::Mock->NULL_RESULTSET
322
        },
323
        {
324
            statement => 'SELECT day, month FROM repeatable_holidays WHERE branchcode = ? AND weekday IS NULL',
325
            results => [
326
                            ['day', 'month'],
327
                            [24,6]
328
                       ]
329
        }
330
   ));
331
    $dbh->{ mock_session } = $sessionOver;
332
    is(_get_chargeable_units('hours', dt_from_string('2014-06-23T12:00:00', 'iso'), dt_from_string('2014-06-25T10:00:00', 'iso'), 'BIB', getOpeningHours()), 6, "Test if _get_chargeable_units takes opening hours and holidays into account.");
333
}
(-)a/tools/holidays.pl (-2 / +65 lines)
Lines 25-31 use C4::Auth; Link Here
25
use C4::Output;
25
use C4::Output;
26
26
27
use C4::Branch; # GetBranches
27
use C4::Branch; # GetBranches
28
use C4::Calendar;
28
use C4::Calendar qw/setOpeningHours getOpeningHours/;
29
30
use C4::Dates;
29
31
30
my $input = new CGI;
32
my $input = new CGI;
31
33
Lines 81-86 for my $thisbranch ( Link Here
81
# branches calculated - put branch codes in a single string so they can be passed in a form
83
# branches calculated - put branch codes in a single string so they can be passed in a form
82
my $branchcodes = join '|', keys %{$branches};
84
my $branchcodes = join '|', keys %{$branches};
83
85
86
87
# Get opening hours
88
89
my $j;
90
for ($j=0; $j<7; $j++) {
91
    my $openhour    = $input->param('openhour_'.$j);
92
    my $openmin     = $input->param('openmin_'.$j);
93
    my $closehour   = $input->param('closehour_'.$j);
94
    my $closemin    = $input->param('closemin_'.$j);
95
    my $weekcode    = $input->param('weekcode_'.$j);
96
97
    my $confirmhour = $input->param('confirm');
98
    if ($confirmhour) {
99
        my $openh = $openhour;
100
        $openh .= ":".$openmin.":00";
101
        my $closeh = $closehour;
102
        $closeh .= ":".$closemin.":00";
103
104
        setOpeningHours($branch, $weekcode, $openh, $closeh);
105
    }
106
}
107
84
# Get all the holidays
108
# Get all the holidays
85
109
86
my $calendar = C4::Calendar->new(branchcode => $branch);
110
my $calendar = C4::Calendar->new(branchcode => $branch);
Lines 146-151 foreach my $yearMonthDay (keys %$single_holidays) { Link Here
146
    push @holidays, \%holiday;
170
    push @holidays, \%holiday;
147
}
171
}
148
172
173
my $tabhour = getOpeningHours($branch);
174
my $openhourbranch;
175
my $openminbranch;
176
my $closehourbranch;
177
my $closeminbranch;
178
my @tabschedule;
179
foreach my $schedule (keys %$tabhour) {
180
    my $hourop = $tabhour->{$schedule}->{'openhour'};
181
    my $closeop = $tabhour->{$schedule}->{'closehour'};
182
    my %row;
183
184
    my @tab1 = split(/:/, $hourop);
185
    $openhourbranch = $tab1[0];
186
    $openminbranch = $tab1[1];
187
188
    my @tab2 = split(/:/, $closeop);
189
    $closehourbranch = $tab2[0];
190
    $closeminbranch = $tab2[1];
191
192
    %row = (dayb => $tabhour->{$schedule}->{'weekcode'},
193
            openhourb => $openhourbranch,
194
            openminb => $openminbranch,
195
            closehourb => $closehourbranch,
196
            closeminb => $closeminbranch);
197
    push @tabschedule, \%row;
198
}
199
200
my @hours;
201
my @minutes = ('00','15','30','45');
202
my $i;
203
for ($i=0; $i<=23; $i++) {
204
    $hours[$i] = ($i<10) ? "0".$i:$i;
205
}
206
207
my @tabdays = ('0','1','2','3','4','5','6');
208
149
$template->param(
209
$template->param(
150
    WEEK_DAYS_LOOP           => \@week_days,
210
    WEEK_DAYS_LOOP           => \@week_days,
151
    branchloop               => \@branchloop,
211
    branchloop               => \@branchloop,
Lines 158-163 $template->param( Link Here
158
    branch                   => $branch,
218
    branch                   => $branch,
159
    branchname               => $branchname,
219
    branchname               => $branchname,
160
    branch                   => $branch,
220
    branch                   => $branch,
221
    hours             => \@hours,
222
    minutes             => \@minutes,
223
    tabdays             => \@tabdays,
224
    tabschedule             => \@tabschedule,
161
);
225
);
162
226
163
# Shows the template with the real values replaced
227
# Shows the template with the real values replaced
164
- 

Return to bug 8133