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

(-)a/C4/Circulation.pm (-44 / +43 lines)
Lines 308-314 sub transferbook { Link Here
308
    my $messages;
308
    my $messages;
309
    my $dotransfer      = 1;
309
    my $dotransfer      = 1;
310
    my $itemnumber = GetItemnumberFromBarcode( $barcode );
310
    my $itemnumber = GetItemnumberFromBarcode( $barcode );
311
    my $issue      = Koha::Issues->find({ itemnumber => $itemnumber });
311
    my $issue      = Koha::Checkouts->find({ itemnumber => $itemnumber });
312
    my $biblio = GetBiblioFromItemNumber($itemnumber);
312
    my $biblio = GetBiblioFromItemNumber($itemnumber);
313
313
314
    # bad barcode..
314
    # bad barcode..
Lines 1829-1839 sub AddReturn { Link Here
1829
    my $biblio   = $item_level_itypes ? undef : GetBiblioData( $item->{ biblionumber } ); # don't get bib data unless we need it
1829
    my $biblio   = $item_level_itypes ? undef : GetBiblioData( $item->{ biblionumber } ); # don't get bib data unless we need it
1830
    my $itemtype = $item_level_itypes ? $item->{itype} : $biblio->{itemtype};
1830
    my $itemtype = $item_level_itypes ? $item->{itype} : $biblio->{itemtype};
1831
1831
1832
    my $issue  = GetItemIssue($itemnumber);
1832
    my $issue  = Koha::Checkouts->find( { itemnumber => $itemnumber } );
1833
    if ($issue and $issue->{borrowernumber}) {
1833
    if ( $issue ) {
1834
        $borrower = C4::Members::GetMember( borrowernumber => $issue->{borrowernumber} )
1834
        $borrower = C4::Members::GetMember( borrowernumber => $issue->borrowernumber )
1835
            or die "Data inconsistency: barcode $barcode (itemnumber:$itemnumber) claims to be issued to non-existent borrowernumber '$issue->{borrowernumber}'\n"
1835
            or die "Data inconsistency: barcode $barcode (itemnumber:$itemnumber) claims to be issued to non-existent borrowernumber '" . $issue->borrowernumber . "'\n"
1836
                . Dumper($issue) . "\n";
1836
                . Dumper($issue->unblessed) . "\n";
1837
    } else {
1837
    } else {
1838
        $messages->{'NotIssued'} = $barcode;
1838
        $messages->{'NotIssued'} = $barcode;
1839
        # even though item is not on loan, it may still be transferred;  therefore, get current branch info
1839
        # even though item is not on loan, it may still be transferred;  therefore, get current branch info
Lines 1915-1921 sub AddReturn { Link Here
1915
    my $today = DateTime->now( time_zone => C4::Context->tz() );
1915
    my $today = DateTime->now( time_zone => C4::Context->tz() );
1916
1916
1917
    if ($doreturn) {
1917
    if ($doreturn) {
1918
        my $datedue = $issue->{date_due};
1918
        my $is_overdue;
1919
        die "The item is not issed and cannot be returned" unless $issue; # Just in case...
1919
        $borrower or warn "AddReturn without current borrower";
1920
        $borrower or warn "AddReturn without current borrower";
1920
		my $circControlBranch;
1921
		my $circControlBranch;
1921
        if ($dropbox) {
1922
        if ($dropbox) {
Lines 1924-1934 sub AddReturn { Link Here
1924
            # FIXME: check issuedate > returndate, factoring in holidays
1925
            # FIXME: check issuedate > returndate, factoring in holidays
1925
1926
1926
            $circControlBranch = _GetCircControlBranch($item,$borrower);
1927
            $circControlBranch = _GetCircControlBranch($item,$borrower);
1927
            $issue->{'overdue'} = DateTime->compare($issue->{'date_due'}, $dropboxdate ) == -1 ? 1 : 0;
1928
            $is_overdue = $issue->is_overdue( $dropboxdate );
1928
        }
1929
        }
1929
1930
1930
        if ($borrowernumber) {
1931
        if ($borrowernumber) {
1931
            if ( ( C4::Context->preference('CalculateFinesOnReturn') && $issue->{'overdue'} ) || $return_date ) {
1932
            if ( ( C4::Context->preference('CalculateFinesOnReturn') && $is_overdue ) || $return_date ) {
1932
                _CalculateAndUpdateFine( { issue => $issue, item => $item, borrower => $borrower, return_date => $return_date } );
1933
                _CalculateAndUpdateFine( { issue => $issue, item => $item, borrower => $borrower, return_date => $return_date } );
1933
            }
1934
            }
1934
1935
Lines 1950-1956 sub AddReturn { Link Here
1950
1951
1951
        }
1952
        }
1952
1953
1953
        ModItem({ onloan => undef }, $issue->{'biblionumber'}, $item->{'itemnumber'});
1954
        ModItem({ onloan => undef }, $item->{biblionumber}, $item->{'itemnumber'});
1954
    }
1955
    }
1955
1956
1956
    # the holdingbranch is updated if the document is returned to another location.
1957
    # the holdingbranch is updated if the document is returned to another location.
Lines 2010-2027 sub AddReturn { Link Here
2010
    if ($borrowernumber) {
2011
    if ($borrowernumber) {
2011
        my $fix = _FixOverduesOnReturn($borrowernumber, $item->{itemnumber}, $exemptfine, $dropbox);
2012
        my $fix = _FixOverduesOnReturn($borrowernumber, $item->{itemnumber}, $exemptfine, $dropbox);
2012
        defined($fix) or warn "_FixOverduesOnReturn($borrowernumber, $item->{itemnumber}...) failed!";  # zero is OK, check defined
2013
        defined($fix) or warn "_FixOverduesOnReturn($borrowernumber, $item->{itemnumber}...) failed!";  # zero is OK, check defined
2013
        
2014
2014
        if ( $issue->{overdue} && $issue->{date_due} ) {
2015
        if ( $issue and $issue->is_overdue ) {
2015
        # fix fine days
2016
        # fix fine days
2016
            $today = $dropboxdate if $dropbox;
2017
            $today = $dropboxdate if $dropbox;
2017
            my ($debardate,$reminder) = _debar_user_on_return( $borrower, $item, $issue->{date_due}, $today );
2018
            my ($debardate,$reminder) = _debar_user_on_return( $borrower, $item, dt_from_string($issue->date_due), $today );
2018
            if ($reminder){
2019
            if ($reminder){
2019
                $messages->{'PrevDebarred'} = $debardate;
2020
                $messages->{'PrevDebarred'} = $debardate;
2020
            } else {
2021
            } else {
2021
                $messages->{'Debarred'} = $debardate if $debardate;
2022
                $messages->{'Debarred'} = $debardate if $debardate;
2022
            }
2023
            }
2023
        # there's no overdue on the item but borrower had been previously debarred
2024
        # there's no overdue on the item but borrower had been previously debarred
2024
        } elsif ( $issue->{date_due} and $borrower->{'debarred'} ) {
2025
        } elsif ( $issue->date_due and $borrower->{'debarred'} ) {
2025
             if ( $borrower->{debarred} eq "9999-12-31") {
2026
             if ( $borrower->{debarred} eq "9999-12-31") {
2026
                $messages->{'ForeverDebarred'} = $borrower->{'debarred'};
2027
                $messages->{'ForeverDebarred'} = $borrower->{'debarred'};
2027
             } else {
2028
             } else {
Lines 2616-2625 sub CanBookBeRenewed { Link Here
2616
    my $renews = 1;
2617
    my $renews = 1;
2617
2618
2618
    my $item      = GetItem($itemnumber)      or return ( 0, 'no_item' );
2619
    my $item      = GetItem($itemnumber)      or return ( 0, 'no_item' );
2619
    my $itemissue = GetItemIssue($itemnumber) or return ( 0, 'no_checkout' );
2620
    my $issue = Koha::Checkouts->find( { itemnumber => $itemnumber } ) or return ( 0, 'no_checkout' );
2620
    return ( 0, 'onsite_checkout' ) if $itemissue->{onsite_checkout};
2621
    return ( 0, 'onsite_checkout' ) if $issue->onsite_checkout;
2621
2622
2622
    $borrowernumber ||= $itemissue->{borrowernumber};
2623
    $borrowernumber ||= $issue->borrowernumber;
2623
    my $borrower = C4::Members::GetMember( borrowernumber => $borrowernumber )
2624
    my $borrower = C4::Members::GetMember( borrowernumber => $borrowernumber )
2624
      or return;
2625
      or return;
2625
2626
Lines 2702-2708 sub CanBookBeRenewed { Link Here
2702
    );
2703
    );
2703
2704
2704
    return ( 0, "too_many" )
2705
    return ( 0, "too_many" )
2705
      if not $issuing_rule or $issuing_rule->renewalsallowed <= $itemissue->{renewals};
2706
      if not $issuing_rule or $issuing_rule->renewalsallowed <= $issue->renewals;
2706
2707
2707
    my $overduesblockrenewing = C4::Context->preference('OverduesBlockRenewing');
2708
    my $overduesblockrenewing = C4::Context->preference('OverduesBlockRenewing');
2708
    my $restrictionblockrenewing = C4::Context->preference('RestrictionBlockRenewing');
2709
    my $restrictionblockrenewing = C4::Context->preference('RestrictionBlockRenewing');
Lines 2712-2728 sub CanBookBeRenewed { Link Here
2712
2713
2713
    if ( $restricted and $restrictionblockrenewing ) {
2714
    if ( $restricted and $restrictionblockrenewing ) {
2714
        return ( 0, 'restriction');
2715
        return ( 0, 'restriction');
2715
    } elsif ( ($hasoverdues and $overduesblockrenewing eq 'block') || ($itemissue->{overdue} and $overduesblockrenewing eq 'blockitem') ) {
2716
    } elsif ( ($hasoverdues and $overduesblockrenewing eq 'block') || ($issue->is_overdue and $overduesblockrenewing eq 'blockitem') ) {
2716
        return ( 0, 'overdue');
2717
        return ( 0, 'overdue');
2717
    }
2718
    }
2718
2719
2719
    if ( $itemissue->{auto_renew}
2720
    if ( $issue->auto_renew
2720
        and defined $issuing_rule->no_auto_renewal_after
2721
        and defined $issuing_rule->no_auto_renewal_after
2721
                and $issuing_rule->no_auto_renewal_after ne "" ) {
2722
                and $issuing_rule->no_auto_renewal_after ne "" ) {
2722
2723
2723
        # Get issue_date and add no_auto_renewal_after
2724
        # Get issue_date and add no_auto_renewal_after
2724
        # If this is greater than today, it's too late for renewal.
2725
        # If this is greater than today, it's too late for renewal.
2725
        my $maximum_renewal_date = dt_from_string($itemissue->{issuedate});
2726
        my $maximum_renewal_date = dt_from_string($issue->issuedate, 'sql');
2726
        $maximum_renewal_date->add(
2727
        $maximum_renewal_date->add(
2727
            $issuing_rule->lengthunit => $issuing_rule->no_auto_renewal_after
2728
            $issuing_rule->lengthunit => $issuing_rule->no_auto_renewal_after
2728
        );
2729
        );
Lines 2737-2745 sub CanBookBeRenewed { Link Here
2737
    {
2738
    {
2738
2739
2739
        # Calculate soonest renewal by subtracting 'No renewal before' from due date
2740
        # Calculate soonest renewal by subtracting 'No renewal before' from due date
2740
        my $soonestrenewal =
2741
        my $soonestrenewal = dt_from_string( $issue->date_due, 'sql' )->subtract(
2741
          $itemissue->{date_due}->clone()
2742
          ->subtract(
2743
            $issuing_rule->lengthunit => $issuing_rule->norenewalbefore );
2742
            $issuing_rule->lengthunit => $issuing_rule->norenewalbefore );
2744
2743
2745
        # Depending on syspref reset the exact time, only check the date
2744
        # Depending on syspref reset the exact time, only check the date
Lines 2751-2770 sub CanBookBeRenewed { Link Here
2751
2750
2752
        if ( $soonestrenewal > DateTime->now( time_zone => C4::Context->tz() ) )
2751
        if ( $soonestrenewal > DateTime->now( time_zone => C4::Context->tz() ) )
2753
        {
2752
        {
2754
            return ( 0, "auto_too_soon" ) if $itemissue->{auto_renew};
2753
            return ( 0, "auto_too_soon" ) if $issue->auto_renew;
2755
            return ( 0, "too_soon" );
2754
            return ( 0, "too_soon" );
2756
        }
2755
        }
2757
        elsif ( $itemissue->{auto_renew} ) {
2756
        elsif ( $issue->auto_renew ) {
2758
            return ( 0, "auto_renew" );
2757
            return ( 0, "auto_renew" );
2759
        }
2758
        }
2760
    }
2759
    }
2761
2760
2762
    # Fallback for automatic renewals:
2761
    # Fallback for automatic renewals:
2763
    # If norenewalbefore is undef, don't renew before due date.
2762
    # If norenewalbefore is undef, don't renew before due date.
2764
    if ( $itemissue->{auto_renew} ) {
2763
    if ( $issue->auto_renew ) {
2765
        my $now = dt_from_string;
2764
        my $now = dt_from_string;
2766
        return ( 0, "auto_renew" )
2765
        return ( 0, "auto_renew" )
2767
          if $now >= $itemissue->{date_due};
2766
          if $now >= dt_from_string( $issue->date_due, 'sql' );
2768
        return ( 0, "auto_too_soon" );
2767
        return ( 0, "auto_too_soon" );
2769
    }
2768
    }
2770
2769
Lines 2808-2818 sub AddRenewal { Link Here
2808
    my $dbh = C4::Context->dbh;
2807
    my $dbh = C4::Context->dbh;
2809
2808
2810
    # Find the issues record for this book
2809
    # Find the issues record for this book
2811
    my $issuedata  = GetItemIssue($itemnumber);
2810
    my $issue = Koha::Checkouts->find( { itemnumber => $itemnumber } );
2812
2811
2813
    return unless ( $issuedata );
2812
    return unless $issue;
2814
2813
2815
    $borrowernumber ||= $issuedata->{borrowernumber};
2814
    $borrowernumber ||= $issue->borrowernumber;
2816
2815
2817
    if ( defined $datedue && ref $datedue ne 'DateTime' ) {
2816
    if ( defined $datedue && ref $datedue ne 'DateTime' ) {
2818
        carp 'Invalid date passed to AddRenewal.';
2817
        carp 'Invalid date passed to AddRenewal.';
Lines 2821-2828 sub AddRenewal { Link Here
2821
2820
2822
    my $borrower = C4::Members::GetMember( borrowernumber => $borrowernumber ) or return;
2821
    my $borrower = C4::Members::GetMember( borrowernumber => $borrowernumber ) or return;
2823
2822
2824
    if ( C4::Context->preference('CalculateFinesOnReturn') && $issuedata->{overdue} ) {
2823
    if ( C4::Context->preference('CalculateFinesOnReturn') && $issue->is_overdue ) {
2825
        _CalculateAndUpdateFine( { issue => $issuedata, item => $item, borrower => $borrower } );
2824
        _CalculateAndUpdateFine( { issue => $issue, item => $item, borrower => $borrower } );
2826
    }
2825
    }
2827
    _FixOverduesOnReturn( $borrowernumber, $itemnumber );
2826
    _FixOverduesOnReturn( $borrowernumber, $itemnumber );
2828
2827
Lines 2834-2847 sub AddRenewal { Link Here
2834
        my $itemtype = (C4::Context->preference('item-level_itypes')) ? $biblio->{'itype'} : $biblio->{'itemtype'};
2833
        my $itemtype = (C4::Context->preference('item-level_itypes')) ? $biblio->{'itype'} : $biblio->{'itemtype'};
2835
2834
2836
        $datedue = (C4::Context->preference('RenewalPeriodBase') eq 'date_due') ?
2835
        $datedue = (C4::Context->preference('RenewalPeriodBase') eq 'date_due') ?
2837
                                        dt_from_string( $issuedata->{date_due} ) :
2836
                                        dt_from_string( $issue->date_due, 'sql' ) :
2838
                                        DateTime->now( time_zone => C4::Context->tz());
2837
                                        DateTime->now( time_zone => C4::Context->tz());
2839
        $datedue =  CalcDateDue($datedue, $itemtype, $issuedata->{'branchcode'}, $borrower, 'is a renewal');
2838
        $datedue =  CalcDateDue($datedue, $itemtype, $issue->branchcode, $borrower, 'is a renewal');
2840
    }
2839
    }
2841
2840
2842
    # Update the issues record to have the new due date, and a new count
2841
    # Update the issues record to have the new due date, and a new count
2843
    # of how many times it has been renewed.
2842
    # of how many times it has been renewed.
2844
    my $renews = $issuedata->{'renewals'} + 1;
2843
    my $renews = $issue->renewals + 1;
2845
    my $sth = $dbh->prepare("UPDATE issues SET date_due = ?, renewals = ?, lastreneweddate = ?
2844
    my $sth = $dbh->prepare("UPDATE issues SET date_due = ?, renewals = ?, lastreneweddate = ?
2846
                            WHERE borrowernumber=? 
2845
                            WHERE borrowernumber=? 
2847
                            AND itemnumber=?"
2846
                            AND itemnumber=?"
Lines 4029-4035 sub _CalculateAndUpdateFine { Link Here
4029
    unless ($item)     { carp "No item passed in!"     && return; }
4028
    unless ($item)     { carp "No item passed in!"     && return; }
4030
    unless ($issue)    { carp "No issue passed in!"    && return; }
4029
    unless ($issue)    { carp "No issue passed in!"    && return; }
4031
4030
4032
    my $datedue = $issue->{date_due};
4031
    my $datedue = dt_from_string( $issue->date_due );
4033
4032
4034
    # we only need to calculate and change the fines if we want to do that on return
4033
    # we only need to calculate and change the fines if we want to do that on return
4035
    # Should be on for hourly loans
4034
    # Should be on for hourly loans
Lines 4037-4043 sub _CalculateAndUpdateFine { Link Here
4037
    my $control_branchcode =
4036
    my $control_branchcode =
4038
        ( $control eq 'ItemHomeLibrary' ) ? $item->{homebranch}
4037
        ( $control eq 'ItemHomeLibrary' ) ? $item->{homebranch}
4039
      : ( $control eq 'PatronLibrary' )   ? $borrower->{branchcode}
4038
      : ( $control eq 'PatronLibrary' )   ? $borrower->{branchcode}
4040
      :                                     $issue->{branchcode};
4039
      :                                     $issue->branchcode;
4041
4040
4042
    my $date_returned = $return_date ? dt_from_string($return_date) : dt_from_string();
4041
    my $date_returned = $return_date ? dt_from_string($return_date) : dt_from_string();
4043
4042
Lines 4049-4057 sub _CalculateAndUpdateFine { Link Here
4049
    if ( C4::Context->preference('finesMode') eq 'production' ) {
4048
    if ( C4::Context->preference('finesMode') eq 'production' ) {
4050
        if ( $amount > 0 ) {
4049
        if ( $amount > 0 ) {
4051
            C4::Overdues::UpdateFine({
4050
            C4::Overdues::UpdateFine({
4052
                issue_id       => $issue->{issue_id},
4051
                issue_id       => $issue->issue_id,
4053
                itemnumber     => $issue->{itemnumber},
4052
                itemnumber     => $issue->itemnumber,
4054
                borrowernumber => $issue->{borrowernumber},
4053
                borrowernumber => $issue->borrowernumber,
4055
                amount         => $amount,
4054
                amount         => $amount,
4056
                type           => $type,
4055
                type           => $type,
4057
                due            => output_pref($datedue),
4056
                due            => output_pref($datedue),
Lines 4063-4071 sub _CalculateAndUpdateFine { Link Here
4063
            # so in this case, we need to drop those fines to 0
4062
            # so in this case, we need to drop those fines to 0
4064
4063
4065
            C4::Overdues::UpdateFine({
4064
            C4::Overdues::UpdateFine({
4066
                issue_id       => $issue->{issue_id},
4065
                issue_id       => $issue->issue_id,
4067
                itemnumber     => $issue->{itemnumber},
4066
                itemnumber     => $issue->itemnumber,
4068
                borrowernumber => $issue->{borrowernumber},
4067
                borrowernumber => $issue->borrowernumber,
4069
                amount         => 0,
4068
                amount         => 0,
4070
                type           => $type,
4069
                type           => $type,
4071
                due            => output_pref($datedue),
4070
                due            => output_pref($datedue),
(-)a/C4/ILSDI/Services.pm (-1 / +1 lines)
Lines 35-41 use DateTime; Link Here
35
use C4::Auth;
35
use C4::Auth;
36
use C4::Members::Attributes qw(GetBorrowerAttributes);
36
use C4::Members::Attributes qw(GetBorrowerAttributes);
37
use Koha::DateUtils;
37
use Koha::DateUtils;
38
use Koha::Issues;
38
use Koha::Checkouts;
39
39
40
use Koha::Libraries;
40
use Koha::Libraries;
41
41
(-)a/circ/returns.pl (-6 / +6 lines)
Lines 185-191 if ( $query->param('reserve_id') ) { Link Here
185
my $borrower;
185
my $borrower;
186
my $returned = 0;
186
my $returned = 0;
187
my $messages;
187
my $messages;
188
my $issueinformation;
188
my $issue;
189
my $itemnumber;
189
my $itemnumber;
190
my $barcode     = $query->param('barcode');
190
my $barcode     = $query->param('barcode');
191
my $exemptfine  = $query->param('exemptfine');
191
my $exemptfine  = $query->param('exemptfine');
Lines 304-324 if ($barcode) { Link Here
304
    );
304
    );
305
305
306
    # do the return
306
    # do the return
307
    ( $returned, $messages, $issueinformation, $borrower ) =
307
    ( $returned, $messages, $issue, $borrower ) =
308
      AddReturn( $barcode, $userenv_branch, $exemptfine, $dropboxmode, $return_date_override, $dropboxdate );
308
      AddReturn( $barcode, $userenv_branch, $exemptfine, $dropboxmode, $return_date_override, $dropboxdate );
309
309
310
    if ($returned) {
310
    if ($returned) {
311
        my $time_now = DateTime->now( time_zone => C4::Context->tz )->truncate( to => 'minute');
311
        my $time_now = DateTime->now( time_zone => C4::Context->tz )->truncate( to => 'minute');
312
        my $duedate = $issueinformation->{date_due}->strftime('%Y-%m-%d %H:%M');
312
        my $date_due_dt = dt_strom_string( $issue->date_due, 'sql' );
313
        my $duedate = $issue ? $date_due_dt->strftime('%Y-%m-%d %H:%M');
313
        $returneditems{0}      = $barcode;
314
        $returneditems{0}      = $barcode;
314
        $riborrowernumber{0}   = $borrower->{'borrowernumber'};
315
        $riborrowernumber{0}   = $borrower->{'borrowernumber'};
315
        $riduedate{0}          = $duedate;
316
        $riduedate{0}          = $duedate;
316
        $input{borrowernumber} = $borrower->{'borrowernumber'};
317
        $input{borrowernumber} = $borrower->{'borrowernumber'};
317
        $input{duedate}        = $duedate;
318
        $input{duedate}        = $duedate;
318
        unless ( $dropboxmode ) {
319
        unless ( $dropboxmode ) {
319
            $input{return_overdue} = 1 if (DateTime->compare($issueinformation->{date_due}, DateTime->now()) == -1);
320
            $input{return_overdue} = 1 if (DateTime->compare($date_due_dt, DateTime->now()) == -1);
320
        } else {
321
        } else {
321
            $input{return_overdue} = 1 if (DateTime->compare($issueinformation->{date_due}, $dropboxdate) == -1);
322
            $input{return_overdue} = 1 if (DateTime->compare($date_due_dt, $dropboxdate) == -1);
322
        }
323
        }
323
        push( @inputloop, \%input );
324
        push( @inputloop, \%input );
324
325
325
- 

Return to bug 17680