|
Lines 307-313
sub transferbook {
Link Here
|
| 307 |
my $messages; |
307 |
my $messages; |
| 308 |
my $dotransfer = 1; |
308 |
my $dotransfer = 1; |
| 309 |
my $itemnumber = GetItemnumberFromBarcode( $barcode ); |
309 |
my $itemnumber = GetItemnumberFromBarcode( $barcode ); |
| 310 |
my $issue = Koha::Issues->find({ itemnumber => $itemnumber }); |
310 |
my $issue = Koha::Checkouts->find({ itemnumber => $itemnumber }); |
| 311 |
my $biblio = GetBiblioFromItemNumber($itemnumber); |
311 |
my $biblio = GetBiblioFromItemNumber($itemnumber); |
| 312 |
|
312 |
|
| 313 |
# bad barcode.. |
313 |
# bad barcode.. |
|
Lines 1828-1838
sub AddReturn {
Link Here
|
| 1828 |
my $biblio = $item_level_itypes ? undef : GetBiblioData( $item->{ biblionumber } ); # don't get bib data unless we need it |
1828 |
my $biblio = $item_level_itypes ? undef : GetBiblioData( $item->{ biblionumber } ); # don't get bib data unless we need it |
| 1829 |
my $itemtype = $item_level_itypes ? $item->{itype} : $biblio->{itemtype}; |
1829 |
my $itemtype = $item_level_itypes ? $item->{itype} : $biblio->{itemtype}; |
| 1830 |
|
1830 |
|
| 1831 |
my $issue = GetItemIssue($itemnumber); |
1831 |
my $issue = Koha::Checkouts->find( { itemnumber => $itemnumber } ); |
| 1832 |
if ($issue and $issue->{borrowernumber}) { |
1832 |
if ( $issue ) { |
| 1833 |
$borrower = C4::Members::GetMember( borrowernumber => $issue->{borrowernumber} ) |
1833 |
$borrower = C4::Members::GetMember( borrowernumber => $issue->borrowernumber ) |
| 1834 |
or die "Data inconsistency: barcode $barcode (itemnumber:$itemnumber) claims to be issued to non-existent borrowernumber '$issue->{borrowernumber}'\n" |
1834 |
or die "Data inconsistency: barcode $barcode (itemnumber:$itemnumber) claims to be issued to non-existent borrowernumber '" . $issue->borrowernumber . "'\n" |
| 1835 |
. Dumper($issue) . "\n"; |
1835 |
. Dumper($issue->unblessed) . "\n"; |
| 1836 |
} else { |
1836 |
} else { |
| 1837 |
$messages->{'NotIssued'} = $barcode; |
1837 |
$messages->{'NotIssued'} = $barcode; |
| 1838 |
# even though item is not on loan, it may still be transferred; therefore, get current branch info |
1838 |
# even though item is not on loan, it may still be transferred; therefore, get current branch info |
|
Lines 1914-1920
sub AddReturn {
Link Here
|
| 1914 |
my $today = DateTime->now( time_zone => C4::Context->tz() ); |
1914 |
my $today = DateTime->now( time_zone => C4::Context->tz() ); |
| 1915 |
|
1915 |
|
| 1916 |
if ($doreturn) { |
1916 |
if ($doreturn) { |
| 1917 |
my $datedue = $issue->{date_due}; |
1917 |
my $is_overdue; |
|
|
1918 |
die "The item is not issed and cannot be returned" unless $issue; # Just in case... |
| 1918 |
$borrower or warn "AddReturn without current borrower"; |
1919 |
$borrower or warn "AddReturn without current borrower"; |
| 1919 |
my $circControlBranch; |
1920 |
my $circControlBranch; |
| 1920 |
if ($dropbox) { |
1921 |
if ($dropbox) { |
|
Lines 1923-1933
sub AddReturn {
Link Here
|
| 1923 |
# FIXME: check issuedate > returndate, factoring in holidays |
1924 |
# FIXME: check issuedate > returndate, factoring in holidays |
| 1924 |
|
1925 |
|
| 1925 |
$circControlBranch = _GetCircControlBranch($item,$borrower); |
1926 |
$circControlBranch = _GetCircControlBranch($item,$borrower); |
| 1926 |
$issue->{'overdue'} = DateTime->compare($issue->{'date_due'}, $dropboxdate ) == -1 ? 1 : 0; |
1927 |
$is_overdue = $issue->is_overdue( $dropboxdate ); |
| 1927 |
} |
1928 |
} |
| 1928 |
|
1929 |
|
| 1929 |
if ($borrowernumber) { |
1930 |
if ($borrowernumber) { |
| 1930 |
if ( ( C4::Context->preference('CalculateFinesOnReturn') && $issue->{'overdue'} ) || $return_date ) { |
1931 |
if ( ( C4::Context->preference('CalculateFinesOnReturn') && $is_overdue ) || $return_date ) { |
| 1931 |
_CalculateAndUpdateFine( { issue => $issue, item => $item, borrower => $borrower, return_date => $return_date } ); |
1932 |
_CalculateAndUpdateFine( { issue => $issue, item => $item, borrower => $borrower, return_date => $return_date } ); |
| 1932 |
} |
1933 |
} |
| 1933 |
|
1934 |
|
|
Lines 1949-1955
sub AddReturn {
Link Here
|
| 1949 |
|
1950 |
|
| 1950 |
} |
1951 |
} |
| 1951 |
|
1952 |
|
| 1952 |
ModItem({ onloan => undef }, $issue->{'biblionumber'}, $item->{'itemnumber'}); |
1953 |
ModItem({ onloan => undef }, $item->{biblionumber}, $item->{'itemnumber'}); |
| 1953 |
} |
1954 |
} |
| 1954 |
|
1955 |
|
| 1955 |
# the holdingbranch is updated if the document is returned to another location. |
1956 |
# the holdingbranch is updated if the document is returned to another location. |
|
Lines 2009-2026
sub AddReturn {
Link Here
|
| 2009 |
if ($borrowernumber) { |
2010 |
if ($borrowernumber) { |
| 2010 |
my $fix = _FixOverduesOnReturn($borrowernumber, $item->{itemnumber}, $exemptfine, $dropbox); |
2011 |
my $fix = _FixOverduesOnReturn($borrowernumber, $item->{itemnumber}, $exemptfine, $dropbox); |
| 2011 |
defined($fix) or warn "_FixOverduesOnReturn($borrowernumber, $item->{itemnumber}...) failed!"; # zero is OK, check defined |
2012 |
defined($fix) or warn "_FixOverduesOnReturn($borrowernumber, $item->{itemnumber}...) failed!"; # zero is OK, check defined |
| 2012 |
|
2013 |
|
| 2013 |
if ( $issue->{overdue} && $issue->{date_due} ) { |
2014 |
if ( $issue and $issue->is_overdue ) { |
| 2014 |
# fix fine days |
2015 |
# fix fine days |
| 2015 |
$today = $dropboxdate if $dropbox; |
2016 |
$today = $dropboxdate if $dropbox; |
| 2016 |
my ($debardate,$reminder) = _debar_user_on_return( $borrower, $item, $issue->{date_due}, $today ); |
2017 |
my ($debardate,$reminder) = _debar_user_on_return( $borrower, $item, dt_from_string($issue->date_due), $today ); |
| 2017 |
if ($reminder){ |
2018 |
if ($reminder){ |
| 2018 |
$messages->{'PrevDebarred'} = $debardate; |
2019 |
$messages->{'PrevDebarred'} = $debardate; |
| 2019 |
} else { |
2020 |
} else { |
| 2020 |
$messages->{'Debarred'} = $debardate if $debardate; |
2021 |
$messages->{'Debarred'} = $debardate if $debardate; |
| 2021 |
} |
2022 |
} |
| 2022 |
# there's no overdue on the item but borrower had been previously debarred |
2023 |
# there's no overdue on the item but borrower had been previously debarred |
| 2023 |
} elsif ( $issue->{date_due} and $borrower->{'debarred'} ) { |
2024 |
} elsif ( $issue->date_due and $borrower->{'debarred'} ) { |
| 2024 |
if ( $borrower->{debarred} eq "9999-12-31") { |
2025 |
if ( $borrower->{debarred} eq "9999-12-31") { |
| 2025 |
$messages->{'ForeverDebarred'} = $borrower->{'debarred'}; |
2026 |
$messages->{'ForeverDebarred'} = $borrower->{'debarred'}; |
| 2026 |
} else { |
2027 |
} else { |
|
Lines 2576-2585
sub CanBookBeRenewed {
Link Here
|
| 2576 |
my $renews = 1; |
2577 |
my $renews = 1; |
| 2577 |
|
2578 |
|
| 2578 |
my $item = GetItem($itemnumber) or return ( 0, 'no_item' ); |
2579 |
my $item = GetItem($itemnumber) or return ( 0, 'no_item' ); |
| 2579 |
my $itemissue = GetItemIssue($itemnumber) or return ( 0, 'no_checkout' ); |
2580 |
my $issue = Koha::Checkouts->find( { itemnumber => $itemnumber } ) or return ( 0, 'no_checkout' ); |
| 2580 |
return ( 0, 'onsite_checkout' ) if $itemissue->{onsite_checkout}; |
2581 |
return ( 0, 'onsite_checkout' ) if $issue->onsite_checkout; |
| 2581 |
|
2582 |
|
| 2582 |
$borrowernumber ||= $itemissue->{borrowernumber}; |
2583 |
$borrowernumber ||= $issue->borrowernumber; |
| 2583 |
my $borrower = C4::Members::GetMember( borrowernumber => $borrowernumber ) |
2584 |
my $borrower = C4::Members::GetMember( borrowernumber => $borrowernumber ) |
| 2584 |
or return; |
2585 |
or return; |
| 2585 |
|
2586 |
|
|
Lines 2662-2668
sub CanBookBeRenewed {
Link Here
|
| 2662 |
); |
2663 |
); |
| 2663 |
|
2664 |
|
| 2664 |
return ( 0, "too_many" ) |
2665 |
return ( 0, "too_many" ) |
| 2665 |
if not $issuing_rule or $issuing_rule->renewalsallowed <= $itemissue->{renewals}; |
2666 |
if not $issuing_rule or $issuing_rule->renewalsallowed <= $issue->renewals; |
| 2666 |
|
2667 |
|
| 2667 |
my $overduesblockrenewing = C4::Context->preference('OverduesBlockRenewing'); |
2668 |
my $overduesblockrenewing = C4::Context->preference('OverduesBlockRenewing'); |
| 2668 |
my $restrictionblockrenewing = C4::Context->preference('RestrictionBlockRenewing'); |
2669 |
my $restrictionblockrenewing = C4::Context->preference('RestrictionBlockRenewing'); |
|
Lines 2672-2688
sub CanBookBeRenewed {
Link Here
|
| 2672 |
|
2673 |
|
| 2673 |
if ( $restricted and $restrictionblockrenewing ) { |
2674 |
if ( $restricted and $restrictionblockrenewing ) { |
| 2674 |
return ( 0, 'restriction'); |
2675 |
return ( 0, 'restriction'); |
| 2675 |
} elsif ( ($hasoverdues and $overduesblockrenewing eq 'block') || ($itemissue->{overdue} and $overduesblockrenewing eq 'blockitem') ) { |
2676 |
} elsif ( ($hasoverdues and $overduesblockrenewing eq 'block') || ($issue->is_overdue and $overduesblockrenewing eq 'blockitem') ) { |
| 2676 |
return ( 0, 'overdue'); |
2677 |
return ( 0, 'overdue'); |
| 2677 |
} |
2678 |
} |
| 2678 |
|
2679 |
|
| 2679 |
if ( $itemissue->{auto_renew} |
2680 |
if ( $issue->auto_renew |
| 2680 |
and defined $issuing_rule->no_auto_renewal_after |
2681 |
and defined $issuing_rule->no_auto_renewal_after |
| 2681 |
and $issuing_rule->no_auto_renewal_after ne "" ) { |
2682 |
and $issuing_rule->no_auto_renewal_after ne "" ) { |
| 2682 |
|
2683 |
|
| 2683 |
# Get issue_date and add no_auto_renewal_after |
2684 |
# Get issue_date and add no_auto_renewal_after |
| 2684 |
# If this is greater than today, it's too late for renewal. |
2685 |
# If this is greater than today, it's too late for renewal. |
| 2685 |
my $maximum_renewal_date = dt_from_string($itemissue->{issuedate}); |
2686 |
my $maximum_renewal_date = dt_from_string($issue->issuedate, 'sql'); |
| 2686 |
$maximum_renewal_date->add( |
2687 |
$maximum_renewal_date->add( |
| 2687 |
$issuing_rule->lengthunit => $issuing_rule->no_auto_renewal_after |
2688 |
$issuing_rule->lengthunit => $issuing_rule->no_auto_renewal_after |
| 2688 |
); |
2689 |
); |
|
Lines 2697-2705
sub CanBookBeRenewed {
Link Here
|
| 2697 |
{ |
2698 |
{ |
| 2698 |
|
2699 |
|
| 2699 |
# Calculate soonest renewal by subtracting 'No renewal before' from due date |
2700 |
# Calculate soonest renewal by subtracting 'No renewal before' from due date |
| 2700 |
my $soonestrenewal = |
2701 |
my $soonestrenewal = dt_from_string( $issue->date_due, 'sql' )->subtract( |
| 2701 |
$itemissue->{date_due}->clone() |
|
|
| 2702 |
->subtract( |
| 2703 |
$issuing_rule->lengthunit => $issuing_rule->norenewalbefore ); |
2702 |
$issuing_rule->lengthunit => $issuing_rule->norenewalbefore ); |
| 2704 |
|
2703 |
|
| 2705 |
# Depending on syspref reset the exact time, only check the date |
2704 |
# Depending on syspref reset the exact time, only check the date |
|
Lines 2711-2730
sub CanBookBeRenewed {
Link Here
|
| 2711 |
|
2710 |
|
| 2712 |
if ( $soonestrenewal > DateTime->now( time_zone => C4::Context->tz() ) ) |
2711 |
if ( $soonestrenewal > DateTime->now( time_zone => C4::Context->tz() ) ) |
| 2713 |
{ |
2712 |
{ |
| 2714 |
return ( 0, "auto_too_soon" ) if $itemissue->{auto_renew}; |
2713 |
return ( 0, "auto_too_soon" ) if $issue->auto_renew; |
| 2715 |
return ( 0, "too_soon" ); |
2714 |
return ( 0, "too_soon" ); |
| 2716 |
} |
2715 |
} |
| 2717 |
elsif ( $itemissue->{auto_renew} ) { |
2716 |
elsif ( $issue->auto_renew ) { |
| 2718 |
return ( 0, "auto_renew" ); |
2717 |
return ( 0, "auto_renew" ); |
| 2719 |
} |
2718 |
} |
| 2720 |
} |
2719 |
} |
| 2721 |
|
2720 |
|
| 2722 |
# Fallback for automatic renewals: |
2721 |
# Fallback for automatic renewals: |
| 2723 |
# If norenewalbefore is undef, don't renew before due date. |
2722 |
# If norenewalbefore is undef, don't renew before due date. |
| 2724 |
if ( $itemissue->{auto_renew} ) { |
2723 |
if ( $issue->auto_renew ) { |
| 2725 |
my $now = dt_from_string; |
2724 |
my $now = dt_from_string; |
| 2726 |
return ( 0, "auto_renew" ) |
2725 |
return ( 0, "auto_renew" ) |
| 2727 |
if $now >= $itemissue->{date_due}; |
2726 |
if $now >= dt_from_string( $issue->date_due, 'sql' ); |
| 2728 |
return ( 0, "auto_too_soon" ); |
2727 |
return ( 0, "auto_too_soon" ); |
| 2729 |
} |
2728 |
} |
| 2730 |
|
2729 |
|
|
Lines 2768-2778
sub AddRenewal {
Link Here
|
| 2768 |
my $dbh = C4::Context->dbh; |
2767 |
my $dbh = C4::Context->dbh; |
| 2769 |
|
2768 |
|
| 2770 |
# Find the issues record for this book |
2769 |
# Find the issues record for this book |
| 2771 |
my $issuedata = GetItemIssue($itemnumber); |
2770 |
my $issue = Koha::Checkouts->find( { itemnumber => $itemnumber } ); |
| 2772 |
|
2771 |
|
| 2773 |
return unless ( $issuedata ); |
2772 |
return unless $issue; |
| 2774 |
|
2773 |
|
| 2775 |
$borrowernumber ||= $issuedata->{borrowernumber}; |
2774 |
$borrowernumber ||= $issue->borrowernumber; |
| 2776 |
|
2775 |
|
| 2777 |
if ( defined $datedue && ref $datedue ne 'DateTime' ) { |
2776 |
if ( defined $datedue && ref $datedue ne 'DateTime' ) { |
| 2778 |
carp 'Invalid date passed to AddRenewal.'; |
2777 |
carp 'Invalid date passed to AddRenewal.'; |
|
Lines 2781-2788
sub AddRenewal {
Link Here
|
| 2781 |
|
2780 |
|
| 2782 |
my $borrower = C4::Members::GetMember( borrowernumber => $borrowernumber ) or return; |
2781 |
my $borrower = C4::Members::GetMember( borrowernumber => $borrowernumber ) or return; |
| 2783 |
|
2782 |
|
| 2784 |
if ( C4::Context->preference('CalculateFinesOnReturn') && $issuedata->{overdue} ) { |
2783 |
if ( C4::Context->preference('CalculateFinesOnReturn') && $issue->is_overdue ) { |
| 2785 |
_CalculateAndUpdateFine( { issue => $issuedata, item => $item, borrower => $borrower } ); |
2784 |
_CalculateAndUpdateFine( { issue => $issue, item => $item, borrower => $borrower } ); |
| 2786 |
} |
2785 |
} |
| 2787 |
_FixOverduesOnReturn( $borrowernumber, $itemnumber ); |
2786 |
_FixOverduesOnReturn( $borrowernumber, $itemnumber ); |
| 2788 |
|
2787 |
|
|
Lines 2794-2807
sub AddRenewal {
Link Here
|
| 2794 |
my $itemtype = (C4::Context->preference('item-level_itypes')) ? $biblio->{'itype'} : $biblio->{'itemtype'}; |
2793 |
my $itemtype = (C4::Context->preference('item-level_itypes')) ? $biblio->{'itype'} : $biblio->{'itemtype'}; |
| 2795 |
|
2794 |
|
| 2796 |
$datedue = (C4::Context->preference('RenewalPeriodBase') eq 'date_due') ? |
2795 |
$datedue = (C4::Context->preference('RenewalPeriodBase') eq 'date_due') ? |
| 2797 |
dt_from_string( $issuedata->{date_due} ) : |
2796 |
dt_from_string( $issue->date_due, 'sql' ) : |
| 2798 |
DateTime->now( time_zone => C4::Context->tz()); |
2797 |
DateTime->now( time_zone => C4::Context->tz()); |
| 2799 |
$datedue = CalcDateDue($datedue, $itemtype, $issuedata->{'branchcode'}, $borrower, 'is a renewal'); |
2798 |
$datedue = CalcDateDue($datedue, $itemtype, $issue->branchcode, $borrower, 'is a renewal'); |
| 2800 |
} |
2799 |
} |
| 2801 |
|
2800 |
|
| 2802 |
# Update the issues record to have the new due date, and a new count |
2801 |
# Update the issues record to have the new due date, and a new count |
| 2803 |
# of how many times it has been renewed. |
2802 |
# of how many times it has been renewed. |
| 2804 |
my $renews = $issuedata->{'renewals'} + 1; |
2803 |
my $renews = $issue->renewals + 1; |
| 2805 |
my $sth = $dbh->prepare("UPDATE issues SET date_due = ?, renewals = ?, lastreneweddate = ? |
2804 |
my $sth = $dbh->prepare("UPDATE issues SET date_due = ?, renewals = ?, lastreneweddate = ? |
| 2806 |
WHERE borrowernumber=? |
2805 |
WHERE borrowernumber=? |
| 2807 |
AND itemnumber=?" |
2806 |
AND itemnumber=?" |
|
Lines 3993-3999
sub _CalculateAndUpdateFine {
Link Here
|
| 3993 |
unless ($item) { carp "No item passed in!" && return; } |
3992 |
unless ($item) { carp "No item passed in!" && return; } |
| 3994 |
unless ($issue) { carp "No issue passed in!" && return; } |
3993 |
unless ($issue) { carp "No issue passed in!" && return; } |
| 3995 |
|
3994 |
|
| 3996 |
my $datedue = $issue->{date_due}; |
3995 |
my $datedue = dt_from_string( $issue->date_due ); |
| 3997 |
|
3996 |
|
| 3998 |
# we only need to calculate and change the fines if we want to do that on return |
3997 |
# we only need to calculate and change the fines if we want to do that on return |
| 3999 |
# Should be on for hourly loans |
3998 |
# Should be on for hourly loans |
|
Lines 4001-4007
sub _CalculateAndUpdateFine {
Link Here
|
| 4001 |
my $control_branchcode = |
4000 |
my $control_branchcode = |
| 4002 |
( $control eq 'ItemHomeLibrary' ) ? $item->{homebranch} |
4001 |
( $control eq 'ItemHomeLibrary' ) ? $item->{homebranch} |
| 4003 |
: ( $control eq 'PatronLibrary' ) ? $borrower->{branchcode} |
4002 |
: ( $control eq 'PatronLibrary' ) ? $borrower->{branchcode} |
| 4004 |
: $issue->{branchcode}; |
4003 |
: $issue->branchcode; |
| 4005 |
|
4004 |
|
| 4006 |
my $date_returned = $return_date ? dt_from_string($return_date) : dt_from_string(); |
4005 |
my $date_returned = $return_date ? dt_from_string($return_date) : dt_from_string(); |
| 4007 |
|
4006 |
|
|
Lines 4013-4021
sub _CalculateAndUpdateFine {
Link Here
|
| 4013 |
if ( C4::Context->preference('finesMode') eq 'production' ) { |
4012 |
if ( C4::Context->preference('finesMode') eq 'production' ) { |
| 4014 |
if ( $amount > 0 ) { |
4013 |
if ( $amount > 0 ) { |
| 4015 |
C4::Overdues::UpdateFine({ |
4014 |
C4::Overdues::UpdateFine({ |
| 4016 |
issue_id => $issue->{issue_id}, |
4015 |
issue_id => $issue->issue_id, |
| 4017 |
itemnumber => $issue->{itemnumber}, |
4016 |
itemnumber => $issue->itemnumber, |
| 4018 |
borrowernumber => $issue->{borrowernumber}, |
4017 |
borrowernumber => $issue->borrowernumber, |
| 4019 |
amount => $amount, |
4018 |
amount => $amount, |
| 4020 |
type => $type, |
4019 |
type => $type, |
| 4021 |
due => output_pref($datedue), |
4020 |
due => output_pref($datedue), |
|
Lines 4027-4035
sub _CalculateAndUpdateFine {
Link Here
|
| 4027 |
# so in this case, we need to drop those fines to 0 |
4026 |
# so in this case, we need to drop those fines to 0 |
| 4028 |
|
4027 |
|
| 4029 |
C4::Overdues::UpdateFine({ |
4028 |
C4::Overdues::UpdateFine({ |
| 4030 |
issue_id => $issue->{issue_id}, |
4029 |
issue_id => $issue->issue_id, |
| 4031 |
itemnumber => $issue->{itemnumber}, |
4030 |
itemnumber => $issue->itemnumber, |
| 4032 |
borrowernumber => $issue->{borrowernumber}, |
4031 |
borrowernumber => $issue->borrowernumber, |
| 4033 |
amount => 0, |
4032 |
amount => 0, |
| 4034 |
type => $type, |
4033 |
type => $type, |
| 4035 |
due => output_pref($datedue), |
4034 |
due => output_pref($datedue), |