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

(-)a/C4/Circulation.pm (-43 / +42 lines)
Lines 306-312 sub transferbook { Link Here
306
    my $messages;
306
    my $messages;
307
    my $dotransfer      = 1;
307
    my $dotransfer      = 1;
308
    my $itemnumber = GetItemnumberFromBarcode( $barcode );
308
    my $itemnumber = GetItemnumberFromBarcode( $barcode );
309
    my $issue      = Koha::Issues->find({ itemnumber => $itemnumber });
309
    my $issue      = Koha::Checkouts->find({ itemnumber => $itemnumber });
310
    my $biblio = GetBiblioFromItemNumber($itemnumber);
310
    my $biblio = GetBiblioFromItemNumber($itemnumber);
311
311
312
    # bad barcode..
312
    # bad barcode..
Lines 1833-1843 sub AddReturn { Link Here
1833
    my $biblio   = $item_level_itypes ? undef : GetBiblioData( $item->{ biblionumber } ); # don't get bib data unless we need it
1833
    my $biblio   = $item_level_itypes ? undef : GetBiblioData( $item->{ biblionumber } ); # don't get bib data unless we need it
1834
    my $itemtype = $item_level_itypes ? $item->{itype} : $biblio->{itemtype};
1834
    my $itemtype = $item_level_itypes ? $item->{itype} : $biblio->{itemtype};
1835
1835
1836
    my $issue  = GetItemIssue($itemnumber);
1836
    my $issue  = Koha::Checkouts->find( { itemnumber => $itemnumber } );
1837
    if ($issue and $issue->{borrowernumber}) {
1837
    if ( $issue ) {
1838
        $borrower = C4::Members::GetMember( borrowernumber => $issue->{borrowernumber} )
1838
        $borrower = C4::Members::GetMember( borrowernumber => $issue->borrowernumber )
1839
            or die "Data inconsistency: barcode $barcode (itemnumber:$itemnumber) claims to be issued to non-existent borrowernumber '$issue->{borrowernumber}'\n"
1839
            or die "Data inconsistency: barcode $barcode (itemnumber:$itemnumber) claims to be issued to non-existent borrowernumber '" . $issue->borrowernumber . "'\n"
1840
                . Dumper($issue) . "\n";
1840
                . Dumper($issue->unblessed) . "\n";
1841
    } else {
1841
    } else {
1842
        $messages->{'NotIssued'} = $barcode;
1842
        $messages->{'NotIssued'} = $barcode;
1843
        # even though item is not on loan, it may still be transferred;  therefore, get current branch info
1843
        # even though item is not on loan, it may still be transferred;  therefore, get current branch info
Lines 1919-1925 sub AddReturn { Link Here
1919
    my $today = DateTime->now( time_zone => C4::Context->tz() );
1919
    my $today = DateTime->now( time_zone => C4::Context->tz() );
1920
1920
1921
    if ($doreturn) {
1921
    if ($doreturn) {
1922
        my $datedue = $issue->{date_due};
1922
        my $is_overdue;
1923
        die "The item is not issed and cannot be returned" unless $issue; # Just in case...
1923
        $borrower or warn "AddReturn without current borrower";
1924
        $borrower or warn "AddReturn without current borrower";
1924
		my $circControlBranch;
1925
		my $circControlBranch;
1925
        if ($dropbox) {
1926
        if ($dropbox) {
Lines 1928-1938 sub AddReturn { Link Here
1928
            # FIXME: check issuedate > returndate, factoring in holidays
1929
            # FIXME: check issuedate > returndate, factoring in holidays
1929
1930
1930
            $circControlBranch = _GetCircControlBranch($item,$borrower);
1931
            $circControlBranch = _GetCircControlBranch($item,$borrower);
1931
            $issue->{'overdue'} = DateTime->compare($issue->{'date_due'}, $dropboxdate ) == -1 ? 1 : 0;
1932
            $is_overdue = $issue->is_overdue( $dropboxdate );
1932
        }
1933
        }
1933
1934
1934
        if ($borrowernumber) {
1935
        if ($borrowernumber) {
1935
            if ( ( C4::Context->preference('CalculateFinesOnReturn') && $issue->{'overdue'} ) || $return_date ) {
1936
            if ( ( C4::Context->preference('CalculateFinesOnReturn') && $is_overdue ) || $return_date ) {
1936
                _CalculateAndUpdateFine( { issue => $issue, item => $item, borrower => $borrower, return_date => $return_date } );
1937
                _CalculateAndUpdateFine( { issue => $issue, item => $item, borrower => $borrower, return_date => $return_date } );
1937
            }
1938
            }
1938
1939
Lines 1954-1960 sub AddReturn { Link Here
1954
1955
1955
        }
1956
        }
1956
1957
1957
        ModItem({ onloan => undef }, $issue->{'biblionumber'}, $item->{'itemnumber'});
1958
        ModItem({ onloan => undef }, $item->{biblionumber}, $item->{'itemnumber'});
1958
    }
1959
    }
1959
1960
1960
    # the holdingbranch is updated if the document is returned to another location.
1961
    # the holdingbranch is updated if the document is returned to another location.
Lines 2014-2031 sub AddReturn { Link Here
2014
    if ($borrowernumber) {
2015
    if ($borrowernumber) {
2015
        my $fix = _FixOverduesOnReturn($borrowernumber, $item->{itemnumber}, $exemptfine, $dropbox);
2016
        my $fix = _FixOverduesOnReturn($borrowernumber, $item->{itemnumber}, $exemptfine, $dropbox);
2016
        defined($fix) or warn "_FixOverduesOnReturn($borrowernumber, $item->{itemnumber}...) failed!";  # zero is OK, check defined
2017
        defined($fix) or warn "_FixOverduesOnReturn($borrowernumber, $item->{itemnumber}...) failed!";  # zero is OK, check defined
2017
        
2018
2018
        if ( $issue->{overdue} && $issue->{date_due} ) {
2019
        if ( $issue and $issue->is_overdue ) {
2019
        # fix fine days
2020
        # fix fine days
2020
            $today = $dropboxdate if $dropbox;
2021
            $today = $dropboxdate if $dropbox;
2021
            my ($debardate,$reminder) = _debar_user_on_return( $borrower, $item, $issue->{date_due}, $today );
2022
            my ($debardate,$reminder) = _debar_user_on_return( $borrower, $item, dt_from_string($issue->date_due), $today );
2022
            if ($reminder){
2023
            if ($reminder){
2023
                $messages->{'PrevDebarred'} = $debardate;
2024
                $messages->{'PrevDebarred'} = $debardate;
2024
            } else {
2025
            } else {
2025
                $messages->{'Debarred'} = $debardate if $debardate;
2026
                $messages->{'Debarred'} = $debardate if $debardate;
2026
            }
2027
            }
2027
        # there's no overdue on the item but borrower had been previously debarred
2028
        # there's no overdue on the item but borrower had been previously debarred
2028
        } elsif ( $issue->{date_due} and $borrower->{'debarred'} ) {
2029
        } elsif ( $issue->date_due and $borrower->{'debarred'} ) {
2029
             if ( $borrower->{debarred} eq "9999-12-31") {
2030
             if ( $borrower->{debarred} eq "9999-12-31") {
2030
                $messages->{'ForeverDebarred'} = $borrower->{'debarred'};
2031
                $messages->{'ForeverDebarred'} = $borrower->{'debarred'};
2031
             } else {
2032
             } else {
Lines 2613-2622 sub CanBookBeRenewed { Link Here
2613
    my $renews = 1;
2614
    my $renews = 1;
2614
2615
2615
    my $item      = GetItem($itemnumber)      or return ( 0, 'no_item' );
2616
    my $item      = GetItem($itemnumber)      or return ( 0, 'no_item' );
2616
    my $itemissue = GetItemIssue($itemnumber) or return ( 0, 'no_checkout' );
2617
    my $issue = Koha::Checkouts->find( { itemnumber => $itemnumber } ) or return ( 0, 'no_checkout' );
2617
    return ( 0, 'onsite_checkout' ) if $itemissue->{onsite_checkout};
2618
    return ( 0, 'onsite_checkout' ) if $issue->onsite_checkout;
2618
2619
2619
    $borrowernumber ||= $itemissue->{borrowernumber};
2620
    $borrowernumber ||= $issue->borrowernumber;
2620
    my $borrower = C4::Members::GetMember( borrowernumber => $borrowernumber )
2621
    my $borrower = C4::Members::GetMember( borrowernumber => $borrowernumber )
2621
      or return;
2622
      or return;
2622
2623
Lines 2698-2704 sub CanBookBeRenewed { Link Here
2698
    );
2699
    );
2699
2700
2700
    return ( 0, "too_many" )
2701
    return ( 0, "too_many" )
2701
      if not $issuing_rule or $issuing_rule->renewalsallowed <= $itemissue->{renewals};
2702
      if not $issuing_rule or $issuing_rule->renewalsallowed <= $issue->renewals;
2702
2703
2703
    my $overduesblockrenewing = C4::Context->preference('OverduesBlockRenewing');
2704
    my $overduesblockrenewing = C4::Context->preference('OverduesBlockRenewing');
2704
    my $restrictionblockrenewing = C4::Context->preference('RestrictionBlockRenewing');
2705
    my $restrictionblockrenewing = C4::Context->preference('RestrictionBlockRenewing');
Lines 2708-2724 sub CanBookBeRenewed { Link Here
2708
2709
2709
    if ( $restricted and $restrictionblockrenewing ) {
2710
    if ( $restricted and $restrictionblockrenewing ) {
2710
        return ( 0, 'restriction');
2711
        return ( 0, 'restriction');
2711
    } elsif ( ($hasoverdues and $overduesblockrenewing eq 'block') || ($itemissue->{overdue} and $overduesblockrenewing eq 'blockitem') ) {
2712
    } elsif ( ($hasoverdues and $overduesblockrenewing eq 'block') || ($issue->is_overdue and $overduesblockrenewing eq 'blockitem') ) {
2712
        return ( 0, 'overdue');
2713
        return ( 0, 'overdue');
2713
    }
2714
    }
2714
2715
2715
    if ( $itemissue->{auto_renew}
2716
    if ( $issue->auto_renew
2716
        and defined $issuing_rule->no_auto_renewal_after
2717
        and defined $issuing_rule->no_auto_renewal_after
2717
                and $issuing_rule->no_auto_renewal_after ne "" ) {
2718
                and $issuing_rule->no_auto_renewal_after ne "" ) {
2718
2719
2719
        # Get issue_date and add no_auto_renewal_after
2720
        # Get issue_date and add no_auto_renewal_after
2720
        # If this is greater than today, it's too late for renewal.
2721
        # If this is greater than today, it's too late for renewal.
2721
        my $maximum_renewal_date = dt_from_string($itemissue->{issuedate});
2722
        my $maximum_renewal_date = dt_from_string($issue->issuedate, 'sql');
2722
        $maximum_renewal_date->add(
2723
        $maximum_renewal_date->add(
2723
            $issuing_rule->lengthunit => $issuing_rule->no_auto_renewal_after
2724
            $issuing_rule->lengthunit => $issuing_rule->no_auto_renewal_after
2724
        );
2725
        );
Lines 2733-2741 sub CanBookBeRenewed { Link Here
2733
    {
2734
    {
2734
2735
2735
        # Calculate soonest renewal by subtracting 'No renewal before' from due date
2736
        # Calculate soonest renewal by subtracting 'No renewal before' from due date
2736
        my $soonestrenewal =
2737
        my $soonestrenewal = dt_from_string( $issue->date_due, 'sql' )->subtract(
2737
          $itemissue->{date_due}->clone()
2738
          ->subtract(
2739
            $issuing_rule->lengthunit => $issuing_rule->norenewalbefore );
2738
            $issuing_rule->lengthunit => $issuing_rule->norenewalbefore );
2740
2739
2741
        # Depending on syspref reset the exact time, only check the date
2740
        # Depending on syspref reset the exact time, only check the date
Lines 2747-2766 sub CanBookBeRenewed { Link Here
2747
2746
2748
        if ( $soonestrenewal > DateTime->now( time_zone => C4::Context->tz() ) )
2747
        if ( $soonestrenewal > DateTime->now( time_zone => C4::Context->tz() ) )
2749
        {
2748
        {
2750
            return ( 0, "auto_too_soon" ) if $itemissue->{auto_renew};
2749
            return ( 0, "auto_too_soon" ) if $issue->auto_renew;
2751
            return ( 0, "too_soon" );
2750
            return ( 0, "too_soon" );
2752
        }
2751
        }
2753
        elsif ( $itemissue->{auto_renew} ) {
2752
        elsif ( $issue->auto_renew ) {
2754
            return ( 0, "auto_renew" );
2753
            return ( 0, "auto_renew" );
2755
        }
2754
        }
2756
    }
2755
    }
2757
2756
2758
    # Fallback for automatic renewals:
2757
    # Fallback for automatic renewals:
2759
    # If norenewalbefore is undef, don't renew before due date.
2758
    # If norenewalbefore is undef, don't renew before due date.
2760
    if ( $itemissue->{auto_renew} ) {
2759
    if ( $issue->auto_renew ) {
2761
        my $now = dt_from_string;
2760
        my $now = dt_from_string;
2762
        return ( 0, "auto_renew" )
2761
        return ( 0, "auto_renew" )
2763
          if $now >= $itemissue->{date_due};
2762
          if $now >= dt_from_string( $issue->date_due, 'sql' );
2764
        return ( 0, "auto_too_soon" );
2763
        return ( 0, "auto_too_soon" );
2765
    }
2764
    }
2766
2765
Lines 2804-2814 sub AddRenewal { Link Here
2804
    my $dbh = C4::Context->dbh;
2803
    my $dbh = C4::Context->dbh;
2805
2804
2806
    # Find the issues record for this book
2805
    # Find the issues record for this book
2807
    my $issuedata  = GetItemIssue($itemnumber);
2806
    my $issue = Koha::Checkouts->find( { itemnumber => $itemnumber } );
2808
2807
2809
    return unless ( $issuedata );
2808
    return unless $issue;
2810
2809
2811
    $borrowernumber ||= $issuedata->{borrowernumber};
2810
    $borrowernumber ||= $issue->borrowernumber;
2812
2811
2813
    if ( defined $datedue && ref $datedue ne 'DateTime' ) {
2812
    if ( defined $datedue && ref $datedue ne 'DateTime' ) {
2814
        carp 'Invalid date passed to AddRenewal.';
2813
        carp 'Invalid date passed to AddRenewal.';
Lines 2817-2824 sub AddRenewal { Link Here
2817
2816
2818
    my $borrower = C4::Members::GetMember( borrowernumber => $borrowernumber ) or return;
2817
    my $borrower = C4::Members::GetMember( borrowernumber => $borrowernumber ) or return;
2819
2818
2820
    if ( C4::Context->preference('CalculateFinesOnReturn') && $issuedata->{overdue} ) {
2819
    if ( C4::Context->preference('CalculateFinesOnReturn') && $issue->is_overdue ) {
2821
        _CalculateAndUpdateFine( { issue => $issuedata, item => $item, borrower => $borrower } );
2820
        _CalculateAndUpdateFine( { issue => $issue, item => $item, borrower => $borrower } );
2822
    }
2821
    }
2823
    _FixOverduesOnReturn( $borrowernumber, $itemnumber );
2822
    _FixOverduesOnReturn( $borrowernumber, $itemnumber );
2824
2823
Lines 2830-2843 sub AddRenewal { Link Here
2830
        my $itemtype = (C4::Context->preference('item-level_itypes')) ? $biblio->{'itype'} : $biblio->{'itemtype'};
2829
        my $itemtype = (C4::Context->preference('item-level_itypes')) ? $biblio->{'itype'} : $biblio->{'itemtype'};
2831
2830
2832
        $datedue = (C4::Context->preference('RenewalPeriodBase') eq 'date_due') ?
2831
        $datedue = (C4::Context->preference('RenewalPeriodBase') eq 'date_due') ?
2833
                                        dt_from_string( $issuedata->{date_due} ) :
2832
                                        dt_from_string( $issue->date_due, 'sql' ) :
2834
                                        DateTime->now( time_zone => C4::Context->tz());
2833
                                        DateTime->now( time_zone => C4::Context->tz());
2835
        $datedue =  CalcDateDue($datedue, $itemtype, _GetCircControlBranch($item, $borrower), $borrower, 'is a renewal');
2834
        $datedue =  CalcDateDue($datedue, $itemtype, _GetCircControlBranch($item, $borrower), $borrower, 'is a renewal');
2836
    }
2835
    }
2837
2836
2838
    # Update the issues record to have the new due date, and a new count
2837
    # Update the issues record to have the new due date, and a new count
2839
    # of how many times it has been renewed.
2838
    # of how many times it has been renewed.
2840
    my $renews = $issuedata->{'renewals'} + 1;
2839
    my $renews = $issue->renewals + 1;
2841
    my $sth = $dbh->prepare("UPDATE issues SET date_due = ?, renewals = ?, lastreneweddate = ?
2840
    my $sth = $dbh->prepare("UPDATE issues SET date_due = ?, renewals = ?, lastreneweddate = ?
2842
                            WHERE borrowernumber=? 
2841
                            WHERE borrowernumber=? 
2843
                            AND itemnumber=?"
2842
                            AND itemnumber=?"
Lines 3982-3988 sub _CalculateAndUpdateFine { Link Here
3982
    unless ($item)     { carp "No item passed in!"     && return; }
3981
    unless ($item)     { carp "No item passed in!"     && return; }
3983
    unless ($issue)    { carp "No issue passed in!"    && return; }
3982
    unless ($issue)    { carp "No issue passed in!"    && return; }
3984
3983
3985
    my $datedue = $issue->{date_due};
3984
    my $datedue = dt_from_string( $issue->date_due );
3986
3985
3987
    # we only need to calculate and change the fines if we want to do that on return
3986
    # we only need to calculate and change the fines if we want to do that on return
3988
    # Should be on for hourly loans
3987
    # Should be on for hourly loans
Lines 3990-3996 sub _CalculateAndUpdateFine { Link Here
3990
    my $control_branchcode =
3989
    my $control_branchcode =
3991
        ( $control eq 'ItemHomeLibrary' ) ? $item->{homebranch}
3990
        ( $control eq 'ItemHomeLibrary' ) ? $item->{homebranch}
3992
      : ( $control eq 'PatronLibrary' )   ? $borrower->{branchcode}
3991
      : ( $control eq 'PatronLibrary' )   ? $borrower->{branchcode}
3993
      :                                     $issue->{branchcode};
3992
      :                                     $issue->branchcode;
3994
3993
3995
    my $date_returned = $return_date ? dt_from_string($return_date) : dt_from_string();
3994
    my $date_returned = $return_date ? dt_from_string($return_date) : dt_from_string();
3996
3995
Lines 4002-4010 sub _CalculateAndUpdateFine { Link Here
4002
    if ( C4::Context->preference('finesMode') eq 'production' ) {
4001
    if ( C4::Context->preference('finesMode') eq 'production' ) {
4003
        if ( $amount > 0 ) {
4002
        if ( $amount > 0 ) {
4004
            C4::Overdues::UpdateFine({
4003
            C4::Overdues::UpdateFine({
4005
                issue_id       => $issue->{issue_id},
4004
                issue_id       => $issue->issue_id,
4006
                itemnumber     => $issue->{itemnumber},
4005
                itemnumber     => $issue->itemnumber,
4007
                borrowernumber => $issue->{borrowernumber},
4006
                borrowernumber => $issue->borrowernumber,
4008
                amount         => $amount,
4007
                amount         => $amount,
4009
                type           => $type,
4008
                type           => $type,
4010
                due            => output_pref($datedue),
4009
                due            => output_pref($datedue),
Lines 4016-4024 sub _CalculateAndUpdateFine { Link Here
4016
            # so in this case, we need to drop those fines to 0
4015
            # so in this case, we need to drop those fines to 0
4017
4016
4018
            C4::Overdues::UpdateFine({
4017
            C4::Overdues::UpdateFine({
4019
                issue_id       => $issue->{issue_id},
4018
                issue_id       => $issue->issue_id,
4020
                itemnumber     => $issue->{itemnumber},
4019
                itemnumber     => $issue->itemnumber,
4021
                borrowernumber => $issue->{borrowernumber},
4020
                borrowernumber => $issue->borrowernumber,
4022
                amount         => 0,
4021
                amount         => 0,
4023
                type           => $type,
4022
                type           => $type,
4024
                due            => output_pref($datedue),
4023
                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::Biblios;
40
use Koha::Biblios;
41
use Koha::Libraries;
41
use Koha::Libraries;
(-)a/circ/returns.pl (-6 / +6 lines)
Lines 187-193 if ( $query->param('reserve_id') ) { Link Here
187
my $borrower;
187
my $borrower;
188
my $returned = 0;
188
my $returned = 0;
189
my $messages;
189
my $messages;
190
my $issueinformation;
190
my $issue;
191
my $itemnumber;
191
my $itemnumber;
192
my $barcode     = $query->param('barcode');
192
my $barcode     = $query->param('barcode');
193
my $exemptfine  = $query->param('exemptfine');
193
my $exemptfine  = $query->param('exemptfine');
Lines 306-326 if ($barcode) { Link Here
306
    );
306
    );
307
307
308
    # do the return
308
    # do the return
309
    ( $returned, $messages, $issueinformation, $borrower ) =
309
    ( $returned, $messages, $issue, $borrower ) =
310
      AddReturn( $barcode, $userenv_branch, $exemptfine, $dropboxmode, $return_date_override, $dropboxdate );
310
      AddReturn( $barcode, $userenv_branch, $exemptfine, $dropboxmode, $return_date_override, $dropboxdate );
311
311
312
    if ($returned) {
312
    if ($returned) {
313
        my $time_now = DateTime->now( time_zone => C4::Context->tz )->truncate( to => 'minute');
313
        my $time_now = DateTime->now( time_zone => C4::Context->tz )->truncate( to => 'minute');
314
        my $duedate = $issueinformation->{date_due}->strftime('%Y-%m-%d %H:%M');
314
        my $date_due_dt = dt_from_string( $issue->date_due, 'sql' );
315
        my $duedate = $date_due_dt->strftime('%Y-%m-%d %H:%M');
315
        $returneditems{0}      = $barcode;
316
        $returneditems{0}      = $barcode;
316
        $riborrowernumber{0}   = $borrower->{'borrowernumber'};
317
        $riborrowernumber{0}   = $borrower->{'borrowernumber'};
317
        $riduedate{0}          = $duedate;
318
        $riduedate{0}          = $duedate;
318
        $input{borrowernumber} = $borrower->{'borrowernumber'};
319
        $input{borrowernumber} = $borrower->{'borrowernumber'};
319
        $input{duedate}        = $duedate;
320
        $input{duedate}        = $duedate;
320
        unless ( $dropboxmode ) {
321
        unless ( $dropboxmode ) {
321
            $input{return_overdue} = 1 if (DateTime->compare($issueinformation->{date_due}, DateTime->now()) == -1);
322
            $input{return_overdue} = 1 if (DateTime->compare($date_due_dt, DateTime->now()) == -1);
322
        } else {
323
        } else {
323
            $input{return_overdue} = 1 if (DateTime->compare($issueinformation->{date_due}, $dropboxdate) == -1);
324
            $input{return_overdue} = 1 if (DateTime->compare($date_due_dt, $dropboxdate) == -1);
324
        }
325
        }
325
        push( @inputloop, \%input );
326
        push( @inputloop, \%input );
326
327
327
- 

Return to bug 17680