Lines 1822-1832
sub AddReturn {
Link Here
|
1822 |
my $biblio = $item_level_itypes ? undef : GetBiblioData( $item->{ biblionumber } ); # don't get bib data unless we need it |
1822 |
my $biblio = $item_level_itypes ? undef : GetBiblioData( $item->{ biblionumber } ); # don't get bib data unless we need it |
1823 |
my $itemtype = $item_level_itypes ? $item->{itype} : $biblio->{itemtype}; |
1823 |
my $itemtype = $item_level_itypes ? $item->{itype} : $biblio->{itemtype}; |
1824 |
|
1824 |
|
1825 |
my $issue = GetItemIssue($itemnumber); |
1825 |
my $issue = Koha::Issues->find( { itemnumber => $itemnumber } ); |
1826 |
if ($issue and $issue->{borrowernumber}) { |
1826 |
if ( $issue ) { |
1827 |
$borrower = C4::Members::GetMemberDetails($issue->{borrowernumber}) |
1827 |
$borrower = C4::Members::GetMemberDetails($issue->borrowernumber) |
1828 |
or die "Data inconsistency: barcode $barcode (itemnumber:$itemnumber) claims to be issued to non-existent borrowernumber '$issue->{borrowernumber}'\n" |
1828 |
or die "Data inconsistency: barcode $barcode (itemnumber:$itemnumber) claims to be issued to non-existent borrowernumber '" . $issue->borrowernumber . "'\n" |
1829 |
. Dumper($issue) . "\n"; |
1829 |
. Dumper($issue->unblessed) . "\n"; |
1830 |
} else { |
1830 |
} else { |
1831 |
$messages->{'NotIssued'} = $barcode; |
1831 |
$messages->{'NotIssued'} = $barcode; |
1832 |
# even though item is not on loan, it may still be transferred; therefore, get current branch info |
1832 |
# even though item is not on loan, it may still be transferred; therefore, get current branch info |
Lines 1908-1914
sub AddReturn {
Link Here
|
1908 |
my $today = DateTime->now( time_zone => C4::Context->tz() ); |
1908 |
my $today = DateTime->now( time_zone => C4::Context->tz() ); |
1909 |
|
1909 |
|
1910 |
if ($doreturn) { |
1910 |
if ($doreturn) { |
1911 |
my $datedue = $issue->{date_due}; |
1911 |
my $is_overdue; |
|
|
1912 |
die "The item is not issed and cannot be returned" unless $issue; # Just in case... |
1912 |
$borrower or warn "AddReturn without current borrower"; |
1913 |
$borrower or warn "AddReturn without current borrower"; |
1913 |
my $circControlBranch; |
1914 |
my $circControlBranch; |
1914 |
if ($dropbox) { |
1915 |
if ($dropbox) { |
Lines 1917-1927
sub AddReturn {
Link Here
|
1917 |
# FIXME: check issuedate > returndate, factoring in holidays |
1918 |
# FIXME: check issuedate > returndate, factoring in holidays |
1918 |
|
1919 |
|
1919 |
$circControlBranch = _GetCircControlBranch($item,$borrower); |
1920 |
$circControlBranch = _GetCircControlBranch($item,$borrower); |
1920 |
$issue->{'overdue'} = DateTime->compare($issue->{'date_due'}, $dropboxdate ) == -1 ? 1 : 0; |
1921 |
$is_overdue = $issue->is_overdue( $dropboxdate ); |
1921 |
} |
1922 |
} |
1922 |
|
1923 |
|
1923 |
if ($borrowernumber) { |
1924 |
if ($borrowernumber) { |
1924 |
if ( ( C4::Context->preference('CalculateFinesOnReturn') && $issue->{'overdue'} ) || $return_date ) { |
1925 |
if ( ( C4::Context->preference('CalculateFinesOnReturn') && $is_overdue ) || $return_date ) { |
1925 |
_CalculateAndUpdateFine( { issue => $issue, item => $item, borrower => $borrower, return_date => $return_date } ); |
1926 |
_CalculateAndUpdateFine( { issue => $issue, item => $item, borrower => $borrower, return_date => $return_date } ); |
1926 |
} |
1927 |
} |
1927 |
|
1928 |
|
Lines 1943-1949
sub AddReturn {
Link Here
|
1943 |
|
1944 |
|
1944 |
} |
1945 |
} |
1945 |
|
1946 |
|
1946 |
ModItem({ onloan => undef }, $issue->{'biblionumber'}, $item->{'itemnumber'}); |
1947 |
ModItem({ onloan => undef }, $item->{biblionumber}, $item->{'itemnumber'}); |
1947 |
} |
1948 |
} |
1948 |
|
1949 |
|
1949 |
# the holdingbranch is updated if the document is returned to another location. |
1950 |
# the holdingbranch is updated if the document is returned to another location. |
Lines 2003-2020
sub AddReturn {
Link Here
|
2003 |
if ($borrowernumber) { |
2004 |
if ($borrowernumber) { |
2004 |
my $fix = _FixOverduesOnReturn($borrowernumber, $item->{itemnumber}, $exemptfine, $dropbox); |
2005 |
my $fix = _FixOverduesOnReturn($borrowernumber, $item->{itemnumber}, $exemptfine, $dropbox); |
2005 |
defined($fix) or warn "_FixOverduesOnReturn($borrowernumber, $item->{itemnumber}...) failed!"; # zero is OK, check defined |
2006 |
defined($fix) or warn "_FixOverduesOnReturn($borrowernumber, $item->{itemnumber}...) failed!"; # zero is OK, check defined |
2006 |
|
2007 |
|
2007 |
if ( $issue->{overdue} && $issue->{date_due} ) { |
2008 |
if ( $issue and $issue->is_overdue ) { |
2008 |
# fix fine days |
2009 |
# fix fine days |
2009 |
$today = $dropboxdate if $dropbox; |
2010 |
$today = $dropboxdate if $dropbox; |
2010 |
my ($debardate,$reminder) = _debar_user_on_return( $borrower, $item, $issue->{date_due}, $today ); |
2011 |
my ($debardate,$reminder) = _debar_user_on_return( $borrower, $item, dt_from_string($issue->date_due), $today ); |
2011 |
if ($reminder){ |
2012 |
if ($reminder){ |
2012 |
$messages->{'PrevDebarred'} = $debardate; |
2013 |
$messages->{'PrevDebarred'} = $debardate; |
2013 |
} else { |
2014 |
} else { |
2014 |
$messages->{'Debarred'} = $debardate if $debardate; |
2015 |
$messages->{'Debarred'} = $debardate if $debardate; |
2015 |
} |
2016 |
} |
2016 |
# there's no overdue on the item but borrower had been previously debarred |
2017 |
# there's no overdue on the item but borrower had been previously debarred |
2017 |
} elsif ( $issue->{date_due} and $borrower->{'debarred'} ) { |
2018 |
} elsif ( $issue->date_due and $borrower->{'debarred'} ) { |
2018 |
if ( $borrower->{debarred} eq "9999-12-31") { |
2019 |
if ( $borrower->{debarred} eq "9999-12-31") { |
2019 |
$messages->{'ForeverDebarred'} = $borrower->{'debarred'}; |
2020 |
$messages->{'ForeverDebarred'} = $borrower->{'debarred'}; |
2020 |
} else { |
2021 |
} else { |
Lines 2676-2685
sub CanBookBeRenewed {
Link Here
|
2676 |
my $renews = 1; |
2677 |
my $renews = 1; |
2677 |
|
2678 |
|
2678 |
my $item = GetItem($itemnumber) or return ( 0, 'no_item' ); |
2679 |
my $item = GetItem($itemnumber) or return ( 0, 'no_item' ); |
2679 |
my $itemissue = GetItemIssue($itemnumber) or return ( 0, 'no_checkout' ); |
2680 |
my $issue = Koha::Issues->find( { itemnumber => $itemnumber } ) or return ( 0, 'no_checkout' ); |
2680 |
return ( 0, 'onsite_checkout' ) if $itemissue->{onsite_checkout}; |
2681 |
return ( 0, 'onsite_checkout' ) if $issue->onsite_checkout; |
2681 |
|
2682 |
|
2682 |
$borrowernumber ||= $itemissue->{borrowernumber}; |
2683 |
$borrowernumber ||= $issue->borrowernumber; |
2683 |
my $borrower = C4::Members::GetMember( borrowernumber => $borrowernumber ) |
2684 |
my $borrower = C4::Members::GetMember( borrowernumber => $borrowernumber ) |
2684 |
or return; |
2685 |
or return; |
2685 |
|
2686 |
|
Lines 2762-2768
sub CanBookBeRenewed {
Link Here
|
2762 |
); |
2763 |
); |
2763 |
|
2764 |
|
2764 |
return ( 0, "too_many" ) |
2765 |
return ( 0, "too_many" ) |
2765 |
if not $issuing_rule or $issuing_rule->renewalsallowed <= $itemissue->{renewals}; |
2766 |
if not $issuing_rule or $issuing_rule->renewalsallowed <= $issue->renewals; |
2766 |
|
2767 |
|
2767 |
my $overduesblockrenewing = C4::Context->preference('OverduesBlockRenewing'); |
2768 |
my $overduesblockrenewing = C4::Context->preference('OverduesBlockRenewing'); |
2768 |
my $restrictionblockrenewing = C4::Context->preference('RestrictionBlockRenewing'); |
2769 |
my $restrictionblockrenewing = C4::Context->preference('RestrictionBlockRenewing'); |
Lines 2772-2788
sub CanBookBeRenewed {
Link Here
|
2772 |
|
2773 |
|
2773 |
if ( $restricted and $restrictionblockrenewing ) { |
2774 |
if ( $restricted and $restrictionblockrenewing ) { |
2774 |
return ( 0, 'restriction'); |
2775 |
return ( 0, 'restriction'); |
2775 |
} elsif ( ($hasoverdues and $overduesblockrenewing eq 'block') || ($itemissue->{overdue} and $overduesblockrenewing eq 'blockitem') ) { |
2776 |
} elsif ( ($hasoverdues and $overduesblockrenewing eq 'block') || ($issue->is_overdue and $overduesblockrenewing eq 'blockitem') ) { |
2776 |
return ( 0, 'overdue'); |
2777 |
return ( 0, 'overdue'); |
2777 |
} |
2778 |
} |
2778 |
|
2779 |
|
2779 |
if ( $itemissue->{auto_renew} |
2780 |
if ( $issue->auto_renew |
2780 |
and defined $issuing_rule->no_auto_renewal_after |
2781 |
and defined $issuing_rule->no_auto_renewal_after |
2781 |
and $issuing_rule->no_auto_renewal_after ne "" ) { |
2782 |
and $issuing_rule->no_auto_renewal_after ne "" ) { |
2782 |
|
2783 |
|
2783 |
# Get issue_date and add no_auto_renewal_after |
2784 |
# Get issue_date and add no_auto_renewal_after |
2784 |
# If this is greater than today, it's too late for renewal. |
2785 |
# If this is greater than today, it's too late for renewal. |
2785 |
my $maximum_renewal_date = dt_from_string($itemissue->{issuedate}); |
2786 |
my $maximum_renewal_date = dt_from_string($issue->issuedate, 'sql'); |
2786 |
$maximum_renewal_date->add( |
2787 |
$maximum_renewal_date->add( |
2787 |
$issuing_rule->lengthunit => $issuing_rule->no_auto_renewal_after |
2788 |
$issuing_rule->lengthunit => $issuing_rule->no_auto_renewal_after |
2788 |
); |
2789 |
); |
Lines 2797-2805
sub CanBookBeRenewed {
Link Here
|
2797 |
{ |
2798 |
{ |
2798 |
|
2799 |
|
2799 |
# Calculate soonest renewal by subtracting 'No renewal before' from due date |
2800 |
# Calculate soonest renewal by subtracting 'No renewal before' from due date |
2800 |
my $soonestrenewal = |
2801 |
my $soonestrenewal = dt_from_string( $issue->date_due, 'sql' )->subtract( |
2801 |
$itemissue->{date_due}->clone() |
|
|
2802 |
->subtract( |
2803 |
$issuing_rule->lengthunit => $issuing_rule->norenewalbefore ); |
2802 |
$issuing_rule->lengthunit => $issuing_rule->norenewalbefore ); |
2804 |
|
2803 |
|
2805 |
# Depending on syspref reset the exact time, only check the date |
2804 |
# Depending on syspref reset the exact time, only check the date |
Lines 2811-2830
sub CanBookBeRenewed {
Link Here
|
2811 |
|
2810 |
|
2812 |
if ( $soonestrenewal > DateTime->now( time_zone => C4::Context->tz() ) ) |
2811 |
if ( $soonestrenewal > DateTime->now( time_zone => C4::Context->tz() ) ) |
2813 |
{ |
2812 |
{ |
2814 |
return ( 0, "auto_too_soon" ) if $itemissue->{auto_renew}; |
2813 |
return ( 0, "auto_too_soon" ) if $issue->auto_renew; |
2815 |
return ( 0, "too_soon" ); |
2814 |
return ( 0, "too_soon" ); |
2816 |
} |
2815 |
} |
2817 |
elsif ( $itemissue->{auto_renew} ) { |
2816 |
elsif ( $issue->auto_renew ) { |
2818 |
return ( 0, "auto_renew" ); |
2817 |
return ( 0, "auto_renew" ); |
2819 |
} |
2818 |
} |
2820 |
} |
2819 |
} |
2821 |
|
2820 |
|
2822 |
# Fallback for automatic renewals: |
2821 |
# Fallback for automatic renewals: |
2823 |
# If norenewalbefore is undef, don't renew before due date. |
2822 |
# If norenewalbefore is undef, don't renew before due date. |
2824 |
if ( $itemissue->{auto_renew} ) { |
2823 |
if ( $issue->auto_renew ) { |
2825 |
my $now = dt_from_string; |
2824 |
my $now = dt_from_string; |
2826 |
return ( 0, "auto_renew" ) |
2825 |
return ( 0, "auto_renew" ) |
2827 |
if $now >= $itemissue->{date_due}; |
2826 |
if $now >= dt_from_string( $issue->date_due, 'sql' ); |
2828 |
return ( 0, "auto_too_soon" ); |
2827 |
return ( 0, "auto_too_soon" ); |
2829 |
} |
2828 |
} |
2830 |
|
2829 |
|
Lines 2868-2878
sub AddRenewal {
Link Here
|
2868 |
my $dbh = C4::Context->dbh; |
2867 |
my $dbh = C4::Context->dbh; |
2869 |
|
2868 |
|
2870 |
# Find the issues record for this book |
2869 |
# Find the issues record for this book |
2871 |
my $issuedata = GetItemIssue($itemnumber); |
2870 |
my $issue = Koha::Issues->find( { itemnumber => $itemnumber } ); |
2872 |
|
2871 |
|
2873 |
return unless ( $issuedata ); |
2872 |
return unless $issue; |
2874 |
|
2873 |
|
2875 |
$borrowernumber ||= $issuedata->{borrowernumber}; |
2874 |
$borrowernumber ||= $issue->borrowernumber; |
2876 |
|
2875 |
|
2877 |
if ( defined $datedue && ref $datedue ne 'DateTime' ) { |
2876 |
if ( defined $datedue && ref $datedue ne 'DateTime' ) { |
2878 |
carp 'Invalid date passed to AddRenewal.'; |
2877 |
carp 'Invalid date passed to AddRenewal.'; |
Lines 2881-2888
sub AddRenewal {
Link Here
|
2881 |
|
2880 |
|
2882 |
my $borrower = C4::Members::GetMember( borrowernumber => $borrowernumber ) or return; |
2881 |
my $borrower = C4::Members::GetMember( borrowernumber => $borrowernumber ) or return; |
2883 |
|
2882 |
|
2884 |
if ( C4::Context->preference('CalculateFinesOnReturn') && $issuedata->{overdue} ) { |
2883 |
if ( C4::Context->preference('CalculateFinesOnReturn') && $issue->is_overdue ) { |
2885 |
_CalculateAndUpdateFine( { issue => $issuedata, item => $item, borrower => $borrower } ); |
2884 |
_CalculateAndUpdateFine( { issue => $issue, item => $item, borrower => $borrower } ); |
2886 |
} |
2885 |
} |
2887 |
_FixOverduesOnReturn( $borrowernumber, $itemnumber ); |
2886 |
_FixOverduesOnReturn( $borrowernumber, $itemnumber ); |
2888 |
|
2887 |
|
Lines 2894-2907
sub AddRenewal {
Link Here
|
2894 |
my $itemtype = (C4::Context->preference('item-level_itypes')) ? $biblio->{'itype'} : $biblio->{'itemtype'}; |
2893 |
my $itemtype = (C4::Context->preference('item-level_itypes')) ? $biblio->{'itype'} : $biblio->{'itemtype'}; |
2895 |
|
2894 |
|
2896 |
$datedue = (C4::Context->preference('RenewalPeriodBase') eq 'date_due') ? |
2895 |
$datedue = (C4::Context->preference('RenewalPeriodBase') eq 'date_due') ? |
2897 |
dt_from_string( $issuedata->{date_due} ) : |
2896 |
dt_from_string( $issue->date_due, 'sql' ) : |
2898 |
DateTime->now( time_zone => C4::Context->tz()); |
2897 |
DateTime->now( time_zone => C4::Context->tz()); |
2899 |
$datedue = CalcDateDue($datedue, $itemtype, $issuedata->{'branchcode'}, $borrower, 'is a renewal'); |
2898 |
$datedue = CalcDateDue($datedue, $itemtype, $issue->branchcode, $borrower, 'is a renewal'); |
2900 |
} |
2899 |
} |
2901 |
|
2900 |
|
2902 |
# Update the issues record to have the new due date, and a new count |
2901 |
# Update the issues record to have the new due date, and a new count |
2903 |
# of how many times it has been renewed. |
2902 |
# of how many times it has been renewed. |
2904 |
my $renews = $issuedata->{'renewals'} + 1; |
2903 |
my $renews = $issue->renewals + 1; |
2905 |
my $sth = $dbh->prepare("UPDATE issues SET date_due = ?, renewals = ?, lastreneweddate = ? |
2904 |
my $sth = $dbh->prepare("UPDATE issues SET date_due = ?, renewals = ?, lastreneweddate = ? |
2906 |
WHERE borrowernumber=? |
2905 |
WHERE borrowernumber=? |
2907 |
AND itemnumber=?" |
2906 |
AND itemnumber=?" |
Lines 4089-4095
sub _CalculateAndUpdateFine {
Link Here
|
4089 |
unless ($item) { carp "No item passed in!" && return; } |
4088 |
unless ($item) { carp "No item passed in!" && return; } |
4090 |
unless ($issue) { carp "No issue passed in!" && return; } |
4089 |
unless ($issue) { carp "No issue passed in!" && return; } |
4091 |
|
4090 |
|
4092 |
my $datedue = $issue->{date_due}; |
4091 |
my $datedue = dt_from_string( $issue->date_due ); |
4093 |
|
4092 |
|
4094 |
# we only need to calculate and change the fines if we want to do that on return |
4093 |
# we only need to calculate and change the fines if we want to do that on return |
4095 |
# Should be on for hourly loans |
4094 |
# Should be on for hourly loans |
Lines 4097-4103
sub _CalculateAndUpdateFine {
Link Here
|
4097 |
my $control_branchcode = |
4096 |
my $control_branchcode = |
4098 |
( $control eq 'ItemHomeLibrary' ) ? $item->{homebranch} |
4097 |
( $control eq 'ItemHomeLibrary' ) ? $item->{homebranch} |
4099 |
: ( $control eq 'PatronLibrary' ) ? $borrower->{branchcode} |
4098 |
: ( $control eq 'PatronLibrary' ) ? $borrower->{branchcode} |
4100 |
: $issue->{branchcode}; |
4099 |
: $issue->branchcode; |
4101 |
|
4100 |
|
4102 |
my $date_returned = $return_date ? dt_from_string($return_date) : dt_from_string(); |
4101 |
my $date_returned = $return_date ? dt_from_string($return_date) : dt_from_string(); |
4103 |
|
4102 |
|
Lines 4109-4117
sub _CalculateAndUpdateFine {
Link Here
|
4109 |
if ( C4::Context->preference('finesMode') eq 'production' ) { |
4108 |
if ( C4::Context->preference('finesMode') eq 'production' ) { |
4110 |
if ( $amount > 0 ) { |
4109 |
if ( $amount > 0 ) { |
4111 |
C4::Overdues::UpdateFine({ |
4110 |
C4::Overdues::UpdateFine({ |
4112 |
issue_id => $issue->{issue_id}, |
4111 |
issue_id => $issue->issue_id, |
4113 |
itemnumber => $issue->{itemnumber}, |
4112 |
itemnumber => $issue->itemnumber, |
4114 |
borrowernumber => $issue->{borrowernumber}, |
4113 |
borrowernumber => $issue->borrowernumber, |
4115 |
amount => $amount, |
4114 |
amount => $amount, |
4116 |
type => $type, |
4115 |
type => $type, |
4117 |
due => output_pref($datedue), |
4116 |
due => output_pref($datedue), |
Lines 4123-4131
sub _CalculateAndUpdateFine {
Link Here
|
4123 |
# so in this case, we need to drop those fines to 0 |
4122 |
# so in this case, we need to drop those fines to 0 |
4124 |
|
4123 |
|
4125 |
C4::Overdues::UpdateFine({ |
4124 |
C4::Overdues::UpdateFine({ |
4126 |
issue_id => $issue->{issue_id}, |
4125 |
issue_id => $issue->issue_id, |
4127 |
itemnumber => $issue->{itemnumber}, |
4126 |
itemnumber => $issue->itemnumber, |
4128 |
borrowernumber => $issue->{borrowernumber}, |
4127 |
borrowernumber => $issue->borrowernumber, |
4129 |
amount => 0, |
4128 |
amount => 0, |
4130 |
type => $type, |
4129 |
type => $type, |
4131 |
due => output_pref($datedue), |
4130 |
due => output_pref($datedue), |