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

(-)a/C4/Circulation.pm (-230 / +228 lines)
Lines 61-116 use Date::Calc qw( Link Here
61
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
61
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
62
62
63
BEGIN {
63
BEGIN {
64
	require Exporter;
64
    require Exporter;
65
    $VERSION = 3.07.00.049;	# for version checking
65
    $VERSION = 3.07.00.049;    # for version checking
66
	@ISA    = qw(Exporter);
66
    @ISA    = qw(Exporter);
67
67
68
	# FIXME subs that should probably be elsewhere
68
    # FIXME subs that should probably be elsewhere
69
	push @EXPORT, qw(
69
    push @EXPORT, qw(
70
		&barcodedecode
70
        &barcodedecode
71
        &LostItem
71
        &LostItem
72
        &ReturnLostItem
72
        &ReturnLostItem
73
	);
73
    );
74
74
75
	# subs to deal with issuing a book
75
    # subs to deal with issuing a book
76
	push @EXPORT, qw(
76
    push @EXPORT, qw(
77
		&CanBookBeIssued
77
        &CanBookBeIssued
78
		&CanBookBeRenewed
78
        &CanBookBeRenewed
79
		&AddIssue
79
        &AddIssue
80
		&AddRenewal
80
        &AddRenewal
81
		&GetRenewCount
81
        &GetRenewCount
82
        &GetSoonestRenewDate
82
        &GetSoonestRenewDate
83
		&GetItemIssue
83
        &GetItemIssue
84
		&GetItemIssues
84
        &GetItemIssues
85
		&GetIssuingCharges
85
        &GetIssuingCharges
86
		&GetIssuingRule
86
        &GetIssuingRule
87
        &GetBranchBorrowerCircRule
87
        &GetBranchBorrowerCircRule
88
        &GetBranchItemRule
88
        &GetBranchItemRule
89
		&GetBiblioIssues
89
        &GetBiblioIssues
90
		&GetOpenIssue
90
        &GetOpenIssue
91
		&AnonymiseIssueHistory
91
        &AnonymiseIssueHistory
92
        &CheckIfIssuedToPatron
92
        &CheckIfIssuedToPatron
93
        &IsItemIssued
93
        &IsItemIssued
94
	);
94
    );
95
95
96
	# subs to deal with returns
96
    # subs to deal with returns
97
	push @EXPORT, qw(
97
    push @EXPORT, qw(
98
		&AddReturn
98
        &AddReturn
99
        &MarkIssueReturned
99
        &MarkIssueReturned
100
	);
100
    );
101
101
102
	# subs to deal with transfers
102
    # subs to deal with transfers
103
	push @EXPORT, qw(
103
    push @EXPORT, qw(
104
		&transferbook
104
        &transferbook
105
		&GetTransfers
105
        &GetTransfers
106
		&GetTransfersFromTo
106
        &GetTransfersFromTo
107
		&updateWrongTransfer
107
        &updateWrongTransfer
108
		&DeleteTransfer
108
        &DeleteTransfer
109
                &IsBranchTransferAllowed
109
                &IsBranchTransferAllowed
110
                &CreateBranchTransferLimit
110
                &CreateBranchTransferLimit
111
                &DeleteBranchTransferLimits
111
                &DeleteBranchTransferLimits
112
        &TransferSlip
112
        &TransferSlip
113
	);
113
    );
114
114
115
    # subs to deal with offline circulation
115
    # subs to deal with offline circulation
116
    push @EXPORT, qw(
116
    push @EXPORT, qw(
Lines 146-156 Generic filter function for barcode string. Link Here
146
Called on every circ if the System Pref itemBarcodeInputFilter is set.
146
Called on every circ if the System Pref itemBarcodeInputFilter is set.
147
Will do some manipulation of the barcode for systems that deliver a barcode
147
Will do some manipulation of the barcode for systems that deliver a barcode
148
to circulation.pl that differs from the barcode stored for the item.
148
to circulation.pl that differs from the barcode stored for the item.
149
For proper functioning of this filter, calling the function on the 
149
For proper functioning of this filter, calling the function on the
150
correct barcode string (items.barcode) should return an unaltered barcode.
150
correct barcode string (items.barcode) should return an unaltered barcode.
151
151
152
The optional $filter argument is to allow for testing or explicit 
152
The optional $filter argument is to allow for testing or explicit
153
behavior that ignores the System Pref.  Valid values are the same as the 
153
behavior that ignores the System Pref.  Valid values are the same as the
154
System Pref options.
154
System Pref options.
155
155
156
=cut
156
=cut
Lines 163-192 sub barcodedecode { Link Here
163
    my $branch = C4::Branch::mybranch();
163
    my $branch = C4::Branch::mybranch();
164
    $filter = C4::Context->preference('itemBarcodeInputFilter') unless $filter;
164
    $filter = C4::Context->preference('itemBarcodeInputFilter') unless $filter;
165
    $filter or return $barcode;     # ensure filter is defined, else return untouched barcode
165
    $filter or return $barcode;     # ensure filter is defined, else return untouched barcode
166
	if ($filter eq 'whitespace') {
166
    if ($filter eq 'whitespace') {
167
		$barcode =~ s/\s//g;
167
        $barcode =~ s/\s//g;
168
	} elsif ($filter eq 'cuecat') {
168
    } elsif ($filter eq 'cuecat') {
169
		chomp($barcode);
169
        chomp($barcode);
170
	    my @fields = split( /\./, $barcode );
170
        my @fields = split( /\./, $barcode );
171
	    my @results = map( decode($_), @fields[ 1 .. $#fields ] );
171
        my @results = map( decode($_), @fields[ 1 .. $#fields ] );
172
	    ($#results == 2) and return $results[2];
172
        ($#results == 2) and return $results[2];
173
	} elsif ($filter eq 'T-prefix') {
173
    } elsif ($filter eq 'T-prefix') {
174
		if ($barcode =~ /^[Tt](\d)/) {
174
        if ($barcode =~ /^[Tt](\d)/) {
175
			(defined($1) and $1 eq '0') and return $barcode;
175
            (defined($1) and $1 eq '0') and return $barcode;
176
            $barcode = substr($barcode, 2) + 0;     # FIXME: probably should be substr($barcode, 1)
176
            $barcode = substr($barcode, 2) + 0;     # FIXME: probably should be substr($barcode, 1)
177
		}
177
        }
178
        return sprintf("T%07d", $barcode);
178
        return sprintf("T%07d", $barcode);
179
        # FIXME: $barcode could be "T1", causing warning: substr outside of string
179
        # FIXME: $barcode could be "T1", causing warning: substr outside of string
180
        # Why drop the nonzero digit after the T?
180
        # Why drop the nonzero digit after the T?
181
        # Why pass non-digits (or empty string) to "T%07d"?
181
        # Why pass non-digits (or empty string) to "T%07d"?
182
	} elsif ($filter eq 'libsuite8') {
182
    } elsif ($filter eq 'libsuite8') {
183
		unless($barcode =~ m/^($branch)-/i){	#if barcode starts with branch code its in Koha style. Skip it.
183
        unless($barcode =~ m/^($branch)-/i){    #if barcode starts with branch code its in Koha style. Skip it.
184
			if($barcode =~ m/^(\d)/i){	#Some barcodes even start with 0's & numbers and are assumed to have b as the item type in the libsuite8 software
184
            if($barcode =~ m/^(\d)/i){    #Some barcodes even start with 0's & numbers and are assumed to have b as the item type in the libsuite8 software
185
                                $barcode =~ s/^[0]*(\d+)$/$branch-b-$1/i;
185
                                $barcode =~ s/^[0]*(\d+)$/$branch-b-$1/i;
186
                        }else{
186
                        }else{
187
				$barcode =~ s/^(\D+)[0]*(\d+)$/$branch-$1-$2/i;
187
                $barcode =~ s/^(\D+)[0]*(\d+)$/$branch-$1-$2/i;
188
			}
188
            }
189
		}
189
        }
190
    } elsif ($filter eq 'EAN13') {
190
    } elsif ($filter eq 'EAN13') {
191
        my $ean = CheckDigits('ean');
191
        my $ean = CheckDigits('ean');
192
        if ( $ean->is_valid($barcode) ) {
192
        if ( $ean->is_valid($barcode) ) {
Lines 195-201 sub barcodedecode { Link Here
195
        } else {
195
        } else {
196
            warn "# [$barcode] not valid EAN-13/UPC-A\n";
196
            warn "# [$barcode] not valid EAN-13/UPC-A\n";
197
        }
197
        }
198
	}
198
    }
199
    return $barcode;    # return barcode, modified or not
199
    return $barcode;    # return barcode, modified or not
200
}
200
}
201
201
Lines 240-246 sub decode { Link Here
240
240
241
=head2 transferbook
241
=head2 transferbook
242
242
243
  ($dotransfer, $messages, $iteminformation) = &transferbook($newbranch, 
243
  ($dotransfer, $messages, $iteminformation) = &transferbook($newbranch,
244
                                            $barcode, $ignore_reserves);
244
                                            $barcode, $ignore_reserves);
245
245
246
Transfers an item to a new branch. If the item is currently on loan, it is automatically returned before the actual transfer.
246
Transfers an item to a new branch. If the item is currently on loan, it is automatically returned before the actual transfer.
Lines 256-262 Returns three values: Link Here
256
256
257
=over
257
=over
258
258
259
=item $dotransfer 
259
=item $dotransfer
260
260
261
is true if the transfer was successful.
261
is true if the transfer was successful.
262
262
Lines 325-331 sub transferbook { Link Here
325
        } elsif ( ! IsBranchTransferAllowed( $tbr, $fbr, $biblio->{ C4::Context->preference("BranchTransferLimitsType") } ) ) {
325
        } elsif ( ! IsBranchTransferAllowed( $tbr, $fbr, $biblio->{ C4::Context->preference("BranchTransferLimitsType") } ) ) {
326
            $messages->{'NotAllowed'} = $tbr . "::" . $biblio->{ C4::Context->preference("BranchTransferLimitsType") };
326
            $messages->{'NotAllowed'} = $tbr . "::" . $biblio->{ C4::Context->preference("BranchTransferLimitsType") };
327
            $dotransfer = 0;
327
            $dotransfer = 0;
328
    	}
328
        }
329
    }
329
    }
330
330
331
    # if is permanent...
331
    # if is permanent...
Lines 373-388 sub transferbook { Link Here
373
sub TooMany {
373
sub TooMany {
374
    my $borrower        = shift;
374
    my $borrower        = shift;
375
    my $biblionumber = shift;
375
    my $biblionumber = shift;
376
	my $item		= shift;
376
    my $item        = shift;
377
    my $cat_borrower    = $borrower->{'categorycode'};
377
    my $cat_borrower    = $borrower->{'categorycode'};
378
    my $dbh             = C4::Context->dbh;
378
    my $dbh             = C4::Context->dbh;
379
	my $branch;
379
    my $branch;
380
	# Get which branchcode we need
380
    # Get which branchcode we need
381
	$branch = _GetCircControlBranch($item,$borrower);
381
    $branch = _GetCircControlBranch($item,$borrower);
382
	my $type = (C4::Context->preference('item-level_itypes')) 
382
    my $type = (C4::Context->preference('item-level_itypes'))
383
  			? $item->{'itype'}         # item-level
383
              ? $item->{'itype'}         # item-level
384
			: $item->{'itemtype'};     # biblio-level
384
            : $item->{'itemtype'};     # biblio-level
385
 
385
386
    # given branch, patron category, and item type, determine
386
    # given branch, patron category, and item type, determine
387
    # applicable issuing rule
387
    # applicable issuing rule
388
    my $issuing_rule = GetIssuingRule($cat_borrower, $type, $branch);
388
    my $issuing_rule = GetIssuingRule($cat_borrower, $type, $branch);
Lines 407-414 sub TooMany { Link Here
407
                                    AND   (categorycode = ? OR categorycode = ?)
407
                                    AND   (categorycode = ? OR categorycode = ?)
408
                                    AND   itemtype <> '*'
408
                                    AND   itemtype <> '*'
409
                                  ) ";
409
                                  ) ";
410
            } else { 
410
            } else {
411
                $count_query .= " JOIN  biblioitems USING (biblionumber) 
411
                $count_query .= " JOIN  biblioitems USING (biblionumber)
412
                                  WHERE biblioitems.itemtype NOT IN (
412
                                  WHERE biblioitems.itemtype NOT IN (
413
                                    SELECT itemtype FROM issuingrules
413
                                    SELECT itemtype FROM issuingrules
414
                                    WHERE branchcode = ?
414
                                    WHERE branchcode = ?
Lines 424-431 sub TooMany { Link Here
424
            # specific item type
424
            # specific item type
425
            if (C4::Context->preference('item-level_itypes')) {
425
            if (C4::Context->preference('item-level_itypes')) {
426
                $count_query .= " WHERE items.itype = ? ";
426
                $count_query .= " WHERE items.itype = ? ";
427
            } else { 
427
            } else {
428
                $count_query .= " JOIN  biblioitems USING (biblionumber) 
428
                $count_query .= " JOIN  biblioitems USING (biblionumber)
429
                                  WHERE biblioitems.itemtype= ? ";
429
                                  WHERE biblioitems.itemtype= ? ";
430
            }
430
            }
431
            push @bind_params, $type;
431
            push @bind_params, $type;
Lines 598-604 sub itemissues { Link Here
598
598
599
=head2 CanBookBeIssued
599
=head2 CanBookBeIssued
600
600
601
  ( $issuingimpossible, $needsconfirmation ) =  CanBookBeIssued( $borrower, 
601
  ( $issuingimpossible, $needsconfirmation ) =  CanBookBeIssued( $borrower,
602
                      $barcode, $duedatespec, $inprocess, $ignore_reserves );
602
                      $barcode, $duedatespec, $inprocess, $ignore_reserves );
603
603
604
Check if a book can be issued.
604
Check if a book can be issued.
Lines 627-633 Possible values are : Link Here
627
627
628
=back
628
=back
629
629
630
=head3 INVALID_DATE 
630
=head3 INVALID_DATE
631
631
632
sticky due date is invalid
632
sticky due date is invalid
633
633
Lines 659-665 item withdrawn. Link Here
659
659
660
item is restricted (set by ??)
660
item is restricted (set by ??)
661
661
662
C<$needsconfirmation> a reference to a hash. It contains reasons why the loan 
662
C<$needsconfirmation> a reference to a hash. It contains reasons why the loan
663
could be prevented, but ones that can be overriden by the operator.
663
could be prevented, but ones that can be overriden by the operator.
664
664
665
Possible values are :
665
Possible values are :
Lines 698-712 sub CanBookBeIssued { Link Here
698
698
699
    my $item = GetItem(GetItemnumberFromBarcode( $barcode ));
699
    my $item = GetItem(GetItemnumberFromBarcode( $barcode ));
700
    my $issue = GetItemIssue($item->{itemnumber});
700
    my $issue = GetItemIssue($item->{itemnumber});
701
	my $biblioitem = GetBiblioItemData($item->{biblioitemnumber});
701
    my $biblioitem = GetBiblioItemData($item->{biblioitemnumber});
702
	$item->{'itemtype'}=$item->{'itype'}; 
702
    $item->{'itemtype'}=$item->{'itype'};
703
    my $dbh             = C4::Context->dbh;
703
    my $dbh             = C4::Context->dbh;
704
704
705
    # MANDATORY CHECKS - unless item exists, nothing else matters
705
    # MANDATORY CHECKS - unless item exists, nothing else matters
706
    unless ( $item->{barcode} ) {
706
    unless ( $item->{barcode} ) {
707
        $issuingimpossible{UNKNOWN_BARCODE} = 1;
707
        $issuingimpossible{UNKNOWN_BARCODE} = 1;
708
    }
708
    }
709
	return ( \%issuingimpossible, \%needsconfirmation ) if %issuingimpossible;
709
    return ( \%issuingimpossible, \%needsconfirmation ) if %issuingimpossible;
710
710
711
    #
711
    #
712
    # DUE DATE is OK ? -- should already have checked.
712
    # DUE DATE is OK ? -- should already have checked.
Lines 738-745 sub CanBookBeIssued { Link Here
738
    #
738
    #
739
    # BORROWER STATUS
739
    # BORROWER STATUS
740
    #
740
    #
741
    if ( $borrower->{'category_type'} eq 'X' && (  $item->{barcode}  )) { 
741
    if ( $borrower->{'category_type'} eq 'X' && (  $item->{barcode}  )) {
742
    	# stats only borrower -- add entry to statistics table, and return issuingimpossible{STATS} = 1  .
742
        # stats only borrower -- add entry to statistics table, and return issuingimpossible{STATS} = 1  .
743
        &UpdateStats(C4::Context->userenv->{'branch'},'localuse','','',$item->{'itemnumber'},$item->{'itemtype'},$borrower->{'borrowernumber'}, undef, $item->{'ccode'});
743
        &UpdateStats(C4::Context->userenv->{'branch'},'localuse','','',$item->{'itemnumber'},$item->{'itemtype'},$borrower->{'borrowernumber'}, undef, $item->{'ccode'});
744
        ModDateLastSeen( $item->{'itemnumber'} );
744
        ModDateLastSeen( $item->{'itemnumber'} );
745
        return( { STATS => 1 }, {});
745
        return( { STATS => 1 }, {});
Lines 809-820 sub CanBookBeIssued { Link Here
809
    my ($blocktype, $count) = C4::Members::IsMemberBlocked($borrower->{'borrowernumber'});
809
    my ($blocktype, $count) = C4::Members::IsMemberBlocked($borrower->{'borrowernumber'});
810
    if ($blocktype == -1) {
810
    if ($blocktype == -1) {
811
        ## patron has outstanding overdue loans
811
        ## patron has outstanding overdue loans
812
	    if ( C4::Context->preference("OverduesBlockCirc") eq 'block'){
812
        if ( C4::Context->preference("OverduesBlockCirc") eq 'block'){
813
	        $issuingimpossible{USERBLOCKEDOVERDUE} = $count;
813
            $issuingimpossible{USERBLOCKEDOVERDUE} = $count;
814
	    }
814
        }
815
	    elsif ( C4::Context->preference("OverduesBlockCirc") eq 'confirmation'){
815
        elsif ( C4::Context->preference("OverduesBlockCirc") eq 'confirmation'){
816
	        $needsconfirmation{USERBLOCKEDOVERDUE} = $count;
816
            $needsconfirmation{USERBLOCKEDOVERDUE} = $count;
817
	    }
817
        }
818
    } elsif($blocktype == 1) {
818
    } elsif($blocktype == 1) {
819
        # patron has accrued fine days
819
        # patron has accrued fine days
820
        $issuingimpossible{USERBLOCKEDREMAINING} = $count;
820
        $issuingimpossible{USERBLOCKEDREMAINING} = $count;
Lines 823-829 sub CanBookBeIssued { Link Here
823
#
823
#
824
    # JB34 CHECKS IF BORROWERS DONT HAVE ISSUE TOO MANY BOOKS
824
    # JB34 CHECKS IF BORROWERS DONT HAVE ISSUE TOO MANY BOOKS
825
    #
825
    #
826
	my ($current_loan_count, $max_loans_allowed) = TooMany( $borrower, $item->{biblionumber}, $item );
826
    my ($current_loan_count, $max_loans_allowed) = TooMany( $borrower, $item->{biblionumber}, $item );
827
    # if TooMany max_loans_allowed returns 0 the user doesn't have permission to check out this book
827
    # if TooMany max_loans_allowed returns 0 the user doesn't have permission to check out this book
828
    if (defined $max_loans_allowed && $max_loans_allowed == 0) {
828
    if (defined $max_loans_allowed && $max_loans_allowed == 0) {
829
        $needsconfirmation{PATRON_CANT} = 1;
829
        $needsconfirmation{PATRON_CANT} = 1;
Lines 906-922 sub CanBookBeIssued { Link Here
906
              if ( $borrower->{'branchcode'} ne $userenv->{branch} );
906
              if ( $borrower->{'branchcode'} ne $userenv->{branch} );
907
        }
907
        }
908
    }
908
    }
909
909
    #
910
    # CHECK IF THERE IS RENTAL CHARGES. RENTAL MUST BE CONFIRMED BY THE BORROWER
910
    # CHECK IF THERE IS RENTAL CHARGES. RENTAL MUST BE CONFIRMED BY THE BORROWER
911
    my $sth = $dbh->prepare("SELECT rentalcharge FROM itemtypes WHERE itemtype = ?");
911
    #
912
    $sth->execute( $item->{'itemtype'} );
912
    my ($rentalCharge) = GetIssuingCharges( $item->{'itemnumber'}, $borrower->{'borrowernumber'} );
913
    my $rentalCharge = $sth->fetchrow();
914
    my $rentalConfirmation = C4::Context->preference("RentalFeesCheckoutConfirmation");
913
    my $rentalConfirmation = C4::Context->preference("RentalFeesCheckoutConfirmation");
915
914
916
    if ( $rentalCharge && $rentalConfirmation )
915
    if ( $rentalConfirmation && $rentalCharge != 0 )
917
    {
916
    {
918
        $rentalCharge = sprintf("%.02f \$", $rentalCharge);
917
        $rentalCharge = sprintf("%.02f", $rentalCharge);
919
        $rentalCharge =~ s/\./,/;
920
        $needsconfirmation{RENTALCHARGE} = $rentalCharge;
918
        $needsconfirmation{RENTALCHARGE} = $rentalCharge;
921
    }
919
    }
922
920
Lines 1191-1197 AddIssue does the following things : Link Here
1191
sub AddIssue {
1189
sub AddIssue {
1192
    my ( $borrower, $barcode, $datedue, $cancelreserve, $issuedate, $sipmode) = @_;
1190
    my ( $borrower, $barcode, $datedue, $cancelreserve, $issuedate, $sipmode) = @_;
1193
    my $dbh = C4::Context->dbh;
1191
    my $dbh = C4::Context->dbh;
1194
	my $barcodecheck=CheckValidBarcode($barcode);
1192
    my $barcodecheck=CheckValidBarcode($barcode);
1195
    if ($datedue && ref $datedue ne 'DateTime') {
1193
    if ($datedue && ref $datedue ne 'DateTime') {
1196
        $datedue = dt_from_string($datedue);
1194
        $datedue = dt_from_string($datedue);
1197
    }
1195
    }
Lines 1205-1252 sub AddIssue { Link Here
1205
1203
1206
        }
1204
        }
1207
    }
1205
    }
1208
	if ($borrower and $barcode and $barcodecheck ne '0'){#??? wtf
1206
    if ($borrower and $barcode and $barcodecheck ne '0'){#??? wtf
1209
		# find which item we issue
1207
        # find which item we issue
1210
		my $item = GetItem('', $barcode) or return;	# if we don't get an Item, abort.
1208
        my $item = GetItem('', $barcode) or return;    # if we don't get an Item, abort.
1211
		my $branch = _GetCircControlBranch($item,$borrower);
1209
        my $branch = _GetCircControlBranch($item,$borrower);
1212
		
1210
1213
		# get actual issuing if there is one
1211
        # get actual issuing if there is one
1214
		my $actualissue = GetItemIssue( $item->{itemnumber});
1212
        my $actualissue = GetItemIssue( $item->{itemnumber});
1215
		
1213
1216
		# get biblioinformation for this item
1214
        # get biblioinformation for this item
1217
		my $biblio = GetBiblioFromItemNumber($item->{itemnumber});
1215
        my $biblio = GetBiblioFromItemNumber($item->{itemnumber});
1218
		
1216
1219
		#
1217
        #
1220
		# check if we just renew the issue.
1218
        # check if we just renew the issue.
1221
		#
1219
        #
1222
		if ($actualissue->{borrowernumber} eq $borrower->{'borrowernumber'}) {
1220
        if ($actualissue->{borrowernumber} eq $borrower->{'borrowernumber'}) {
1223
		    $datedue = AddRenewal(
1221
            $datedue = AddRenewal(
1224
			$borrower->{'borrowernumber'},
1222
            $borrower->{'borrowernumber'},
1225
			$item->{'itemnumber'},
1223
            $item->{'itemnumber'},
1226
			$branch,
1224
            $branch,
1227
			$datedue,
1225
            $datedue,
1228
			$issuedate, # here interpreted as the renewal date
1226
            $issuedate, # here interpreted as the renewal date
1229
			);
1227
            );
1230
		}
1228
        }
1231
		else {
1229
        else {
1232
        # it's NOT a renewal
1230
        # it's NOT a renewal
1233
			if ( $actualissue->{borrowernumber}) {
1231
            if ( $actualissue->{borrowernumber}) {
1234
				# This book is currently on loan, but not to the person
1232
                # This book is currently on loan, but not to the person
1235
				# who wants to borrow it now. mark it returned before issuing to the new borrower
1233
                # who wants to borrow it now. mark it returned before issuing to the new borrower
1236
				AddReturn(
1234
                AddReturn(
1237
					$item->{'barcode'},
1235
                    $item->{'barcode'},
1238
					C4::Context->userenv->{'branch'}
1236
                    C4::Context->userenv->{'branch'}
1239
				);
1237
                );
1240
			}
1238
            }
1241
1239
1242
            MoveReserve( $item->{'itemnumber'}, $borrower->{'borrowernumber'}, $cancelreserve );
1240
            MoveReserve( $item->{'itemnumber'}, $borrower->{'borrowernumber'}, $cancelreserve );
1243
			# Starting process for transfer job (checking transfert and validate it if we have one)
1241
            # Starting process for transfer job (checking transfert and validate it if we have one)
1244
            my ($datesent) = GetTransfers($item->{'itemnumber'});
1242
            my ($datesent) = GetTransfers($item->{'itemnumber'});
1245
            if ($datesent) {
1243
            if ($datesent) {
1246
        # 	updating line of branchtranfert to finish it, and changing the to branch value, implement a comment for visibility of this case (maybe for stats ....)
1244
        #     updating line of branchtranfert to finish it, and changing the to branch value, implement a comment for visibility of this case (maybe for stats ....)
1247
                my $sth =
1245
                my $sth =
1248
                    $dbh->prepare(
1246
                    $dbh->prepare(
1249
                    "UPDATE branchtransfers 
1247
                    "UPDATE branchtransfers
1250
                        SET datearrived = now(),
1248
                        SET datearrived = now(),
1251
                        tobranch = ?,
1249
                        tobranch = ?,
1252
                        comments = 'Forced branchtransfer'
1250
                        comments = 'Forced branchtransfer'
Lines 1340-1346 sub AddIssue { Link Here
1340
    logaction("CIRCULATION", "ISSUE", $borrower->{'borrowernumber'}, $biblio->{'itemnumber'})
1338
    logaction("CIRCULATION", "ISSUE", $borrower->{'borrowernumber'}, $biblio->{'itemnumber'})
1341
        if C4::Context->preference("IssueLog");
1339
        if C4::Context->preference("IssueLog");
1342
  }
1340
  }
1343
  return ($datedue);	# not necessarily the same as when it came in!
1341
  return ($datedue);    # not necessarily the same as when it came in!
1344
}
1342
}
1345
1343
1346
=head2 GetLoanLength
1344
=head2 GetLoanLength
Lines 1443-1449 sub GetHardDueDate { Link Here
1443
  my $irule = &GetIssuingRule($borrowertype,$itemtype,branchcode)
1441
  my $irule = &GetIssuingRule($borrowertype,$itemtype,branchcode)
1444
1442
1445
FIXME - This is a copy-paste of GetLoanLength
1443
FIXME - This is a copy-paste of GetLoanLength
1446
as a stop-gap.  Do not wish to change API for GetLoanLength 
1444
as a stop-gap.  Do not wish to change API for GetLoanLength
1447
this close to release.
1445
this close to release.
1448
1446
1449
Get the issuing rule for an itemtype, a borrower type and a branch
1447
Get the issuing rule for an itemtype, a borrower type and a branch
Lines 1457-1463 sub GetIssuingRule { Link Here
1457
    my $sth =  $dbh->prepare( "select * from issuingrules where categorycode=? and itemtype=? and branchcode=? and issuelength is not null"  );
1455
    my $sth =  $dbh->prepare( "select * from issuingrules where categorycode=? and itemtype=? and branchcode=? and issuelength is not null"  );
1458
    my $irule;
1456
    my $irule;
1459
1457
1460
	$sth->execute( $borrowertype, $itemtype, $branchcode );
1458
    $sth->execute( $borrowertype, $itemtype, $branchcode );
1461
    $irule = $sth->fetchrow_hashref;
1459
    $irule = $sth->fetchrow_hashref;
1462
    return $irule if defined($irule) ;
1460
    return $irule if defined($irule) ;
1463
1461
Lines 1498-1504 sub GetIssuingRule { Link Here
1498
  my $branch_cat_rule = GetBranchBorrowerCircRule($branchcode, $categorycode);
1496
  my $branch_cat_rule = GetBranchBorrowerCircRule($branchcode, $categorycode);
1499
1497
1500
Retrieves circulation rule attributes that apply to the given
1498
Retrieves circulation rule attributes that apply to the given
1501
branch and patron category, regardless of item type.  
1499
branch and patron category, regardless of item type.
1502
The return value is a hashref containing the following key:
1500
The return value is a hashref containing the following key:
1503
1501
1504
maxissueqty - maximum number of loans that a
1502
maxissueqty - maximum number of loans that a
Lines 1506-1516 patron of the given category can have at the given Link Here
1506
branch.  If the value is undef, no limit.
1504
branch.  If the value is undef, no limit.
1507
1505
1508
This will first check for a specific branch and
1506
This will first check for a specific branch and
1509
category match from branch_borrower_circ_rules. 
1507
category match from branch_borrower_circ_rules.
1510
1508
1511
If no rule is found, it will then check default_branch_circ_rules
1509
If no rule is found, it will then check default_branch_circ_rules
1512
(same branch, default category).  If no rule is found,
1510
(same branch, default category).  If no rule is found,
1513
it will then check default_borrower_circ_rules (default 
1511
it will then check default_borrower_circ_rules (default
1514
branch, same category), then failing that, default_circ_rules
1512
branch, same category), then failing that, default_circ_rules
1515
(default branch, default category).
1513
(default branch, default category).
1516
1514
Lines 1560-1566 sub GetBranchBorrowerCircRule { Link Here
1560
    if ($result = $sth->fetchrow_hashref()) {
1558
    if ($result = $sth->fetchrow_hashref()) {
1561
        return $result;
1559
        return $result;
1562
    }
1560
    }
1563
  
1561
1564
    # try default branch, default borrower category
1562
    # try default branch, default borrower category
1565
    my $default_query = "SELECT maxissueqty
1563
    my $default_query = "SELECT maxissueqty
1566
                          FROM default_circ_rules";
1564
                          FROM default_circ_rules";
Lines 1569-1575 sub GetBranchBorrowerCircRule { Link Here
1569
    if ($result = $sth->fetchrow_hashref()) {
1567
    if ($result = $sth->fetchrow_hashref()) {
1570
        return $result;
1568
        return $result;
1571
    }
1569
    }
1572
    
1570
1573
    # built-in default circulation rule
1571
    # built-in default circulation rule
1574
    return {
1572
    return {
1575
        maxissueqty => undef,
1573
        maxissueqty => undef,
Lines 1636-1642 sub GetBranchItemRule { Link Here
1636
        $result->{'holdallowed'}  = $search_result->{'holdallowed'}  unless ( defined $result->{'holdallowed'} );
1634
        $result->{'holdallowed'}  = $search_result->{'holdallowed'}  unless ( defined $result->{'holdallowed'} );
1637
        $result->{'returnbranch'} = $search_result->{'returnbranch'} unless ( defined $result->{'returnbranch'} );
1635
        $result->{'returnbranch'} = $search_result->{'returnbranch'} unless ( defined $result->{'returnbranch'} );
1638
    }
1636
    }
1639
    
1637
1640
    # built-in default circulation rule
1638
    # built-in default circulation rule
1641
    $result->{'holdallowed'} = 2 unless ( defined $result->{'holdallowed'} );
1639
    $result->{'holdallowed'} = 2 unless ( defined $result->{'holdallowed'} );
1642
    $result->{'returnbranch'} = 'homebranch' unless ( defined $result->{'returnbranch'} );
1640
    $result->{'returnbranch'} = 'homebranch' unless ( defined $result->{'returnbranch'} );
Lines 1734-1740 sub AddReturn { Link Here
1734
    my $biblio;
1732
    my $biblio;
1735
    my $doreturn       = 1;
1733
    my $doreturn       = 1;
1736
    my $validTransfert = 0;
1734
    my $validTransfert = 0;
1737
    my $stat_type = 'return';    
1735
    my $stat_type = 'return';
1738
1736
1739
    # get information on item
1737
    # get information on item
1740
    my $itemnumber = GetItemnumberFromBarcode( $barcode );
1738
    my $itemnumber = GetItemnumberFromBarcode( $barcode );
Lines 1818-1824 sub AddReturn { Link Here
1818
    if ($doreturn) {
1816
    if ($doreturn) {
1819
        my $datedue = $issue->{date_due};
1817
        my $datedue = $issue->{date_due};
1820
        $borrower or warn "AddReturn without current borrower";
1818
        $borrower or warn "AddReturn without current borrower";
1821
		my $circControlBranch;
1819
        my $circControlBranch;
1822
        if ($dropbox) {
1820
        if ($dropbox) {
1823
            # define circControlBranch only if dropbox mode is set
1821
            # define circControlBranch only if dropbox mode is set
1824
            # don't allow dropbox mode to create an invalid entry in issues (issuedate > today)
1822
            # don't allow dropbox mode to create an invalid entry in issues (issuedate > today)
Lines 1920-1926 sub AddReturn { Link Here
1920
    if ($borrowernumber) {
1918
    if ($borrowernumber) {
1921
        my $fix = _FixOverduesOnReturn($borrowernumber, $item->{itemnumber}, $exemptfine, $dropbox);
1919
        my $fix = _FixOverduesOnReturn($borrowernumber, $item->{itemnumber}, $exemptfine, $dropbox);
1922
        defined($fix) or warn "_FixOverduesOnReturn($borrowernumber, $item->{itemnumber}...) failed!";  # zero is OK, check defined
1920
        defined($fix) or warn "_FixOverduesOnReturn($borrowernumber, $item->{itemnumber}...) failed!";  # zero is OK, check defined
1923
        
1921
1924
        if ( $issue->{overdue} && $issue->{date_due} ) {
1922
        if ( $issue->{overdue} && $issue->{date_due} ) {
1925
        # fix fine days
1923
        # fix fine days
1926
            my ($debardate,$reminder) = _debar_user_on_return( $borrower, $item, $issue->{date_due}, $today );
1924
            my ($debardate,$reminder) = _debar_user_on_return( $borrower, $item, $issue->{date_due}, $today );
Lines 1975-1984 sub AddReturn { Link Here
1975
            branch   => $branch,
1973
            branch   => $branch,
1976
        });
1974
        });
1977
    }
1975
    }
1978
    
1976
1979
    logaction("CIRCULATION", "RETURN", $borrowernumber, $item->{'itemnumber'})
1977
    logaction("CIRCULATION", "RETURN", $borrowernumber, $item->{'itemnumber'})
1980
        if C4::Context->preference("ReturnLog");
1978
        if C4::Context->preference("ReturnLog");
1981
    
1979
1982
    # Remove any OVERDUES related debarment if the borrower has no overdues
1980
    # Remove any OVERDUES related debarment if the borrower has no overdues
1983
    if ( $borrowernumber
1981
    if ( $borrowernumber
1984
      && $borrower->{'debarred'}
1982
      && $borrower->{'debarred'}
Lines 2017-2023 Unconditionally marks an issue as being returned by Link Here
2017
moving the C<issues> row to C<old_issues> and
2015
moving the C<issues> row to C<old_issues> and
2018
setting C<returndate> to the current date, or
2016
setting C<returndate> to the current date, or
2019
the last non-holiday date of the branccode specified in
2017
the last non-holiday date of the branccode specified in
2020
C<dropbox_branch> .  Assumes you've already checked that 
2018
C<dropbox_branch> .  Assumes you've already checked that
2021
it's safe to do this, i.e. last non-holiday > issuedate.
2019
it's safe to do this, i.e. last non-holiday > issuedate.
2022
2020
2023
if C<$returndate> is specified (in iso format), it is used as the date
2021
if C<$returndate> is specified (in iso format), it is used as the date
Lines 2027-2033 C<$privacy> contains the privacy parameter. If the patron has set privacy to 2, Link Here
2027
the old_issue is immediately anonymised
2025
the old_issue is immediately anonymised
2028
2026
2029
Ideally, this function would be internal to C<C4::Circulation>,
2027
Ideally, this function would be internal to C<C4::Circulation>,
2030
not exported, but it is currently needed by one 
2028
not exported, but it is currently needed by one
2031
routine in C<C4::Accounts>.
2029
routine in C<C4::Accounts>.
2032
2030
2033
=cut
2031
=cut
Lines 2157-2163 C<$brn> borrowernumber Link Here
2157
2155
2158
C<$itm> itemnumber
2156
C<$itm> itemnumber
2159
2157
2160
C<$exemptfine> BOOL -- remove overdue charge associated with this issue. 
2158
C<$exemptfine> BOOL -- remove overdue charge associated with this issue.
2161
C<$dropboxmode> BOOL -- remove lastincrement on overdue charge associated with this issue.
2159
C<$dropboxmode> BOOL -- remove lastincrement on overdue charge associated with this issue.
2162
2160
2163
Internal function, called only by AddReturn
2161
Internal function, called only by AddReturn
Lines 2304-2310 sub _FixAccountForLostAndReturned { Link Here
2304
2302
2305
   my $circ_control_branch = _GetCircControlBranch($iteminfos, $borrower);
2303
   my $circ_control_branch = _GetCircControlBranch($iteminfos, $borrower);
2306
2304
2307
Internal function : 
2305
Internal function :
2308
2306
2309
Return the library code to be used to determine which circulation
2307
Return the library code to be used to determine which circulation
2310
policy applies to a transaction.  Looks up the CircControl and
2308
policy applies to a transaction.  Looks up the CircControl and
Lines 2389-2395 Returns a hashref Link Here
2389
sub GetOpenIssue {
2387
sub GetOpenIssue {
2390
  my ( $itemnumber ) = @_;
2388
  my ( $itemnumber ) = @_;
2391
  return unless $itemnumber;
2389
  return unless $itemnumber;
2392
  my $dbh = C4::Context->dbh;  
2390
  my $dbh = C4::Context->dbh;
2393
  my $sth = $dbh->prepare( "SELECT * FROM issues WHERE itemnumber = ? AND returndate IS NULL" );
2391
  my $sth = $dbh->prepare( "SELECT * FROM issues WHERE itemnumber = ? AND returndate IS NULL" );
2394
  $sth->execute( $itemnumber );
2392
  $sth->execute( $itemnumber );
2395
  return $sth->fetchrow_hashref();
2393
  return $sth->fetchrow_hashref();
Lines 2479-2485 Returns reference to an array of hashes Link Here
2479
2477
2480
sub GetItemIssues {
2478
sub GetItemIssues {
2481
    my ( $itemnumber, $history ) = @_;
2479
    my ( $itemnumber, $history ) = @_;
2482
    
2480
2483
    my $today = DateTime->now( time_zome => C4::Context->tz);  # get today date
2481
    my $today = DateTime->now( time_zome => C4::Context->tz);  # get today date
2484
    $today->truncate( to => 'minute' );
2482
    $today->truncate( to => 'minute' );
2485
    my $sql = "SELECT * FROM issues
2483
    my $sql = "SELECT * FROM issues
Lines 2568-2574 sub GetUpcomingDueIssues { Link Here
2568
2566
2569
    my $statement = <<END_SQL;
2567
    my $statement = <<END_SQL;
2570
SELECT issues.*, items.itype as itemtype, items.homebranch, TO_DAYS( date_due )-TO_DAYS( NOW() ) as days_until_due, branches.branchemail
2568
SELECT issues.*, items.itype as itemtype, items.homebranch, TO_DAYS( date_due )-TO_DAYS( NOW() ) as days_until_due, branches.branchemail
2571
FROM issues 
2569
FROM issues
2572
LEFT JOIN items USING (itemnumber)
2570
LEFT JOIN items USING (itemnumber)
2573
LEFT OUTER JOIN branches USING (branchcode)
2571
LEFT OUTER JOIN branches USING (branchcode)
2574
WHERE returndate is NULL
2572
WHERE returndate is NULL
Lines 2576-2582 HAVING days_until_due >= 0 AND days_until_due <= ? Link Here
2576
END_SQL
2574
END_SQL
2577
2575
2578
    my @bind_parameters = ( $params->{'days_in_advance'} );
2576
    my @bind_parameters = ( $params->{'days_in_advance'} );
2579
    
2577
2580
    my $sth = $dbh->prepare( $statement );
2578
    my $sth = $dbh->prepare( $statement );
2581
    $sth->execute( @bind_parameters );
2579
    $sth->execute( @bind_parameters );
2582
    my $upcoming_dues = $sth->fetchall_arrayref({});
2580
    my $upcoming_dues = $sth->fetchall_arrayref({});
Lines 2728-2734 sub AddRenewal { Link Here
2728
    # of how many times it has been renewed.
2726
    # of how many times it has been renewed.
2729
    my $renews = $issuedata->{'renewals'} + 1;
2727
    my $renews = $issuedata->{'renewals'} + 1;
2730
    $sth = $dbh->prepare("UPDATE issues SET date_due = ?, renewals = ?, lastreneweddate = ?
2728
    $sth = $dbh->prepare("UPDATE issues SET date_due = ?, renewals = ?, lastreneweddate = ?
2731
                            WHERE borrowernumber=? 
2729
                            WHERE borrowernumber=?
2732
                            AND itemnumber=?"
2730
                            AND itemnumber=?"
2733
    );
2731
    );
2734
2732
Lines 2744-2750 sub AddRenewal { Link Here
2744
        my $accountno = getnextacctno( $borrowernumber );
2742
        my $accountno = getnextacctno( $borrowernumber );
2745
        my $item = GetBiblioFromItemNumber($itemnumber);
2743
        my $item = GetBiblioFromItemNumber($itemnumber);
2746
        my $manager_id = 0;
2744
        my $manager_id = 0;
2747
        $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv; 
2745
        $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
2748
        $sth = $dbh->prepare(
2746
        $sth = $dbh->prepare(
2749
                "INSERT INTO accountlines
2747
                "INSERT INTO accountlines
2750
                    (date, borrowernumber, accountno, amount, manager_id,
2748
                    (date, borrowernumber, accountno, amount, manager_id,
Lines 2758-2779 sub AddRenewal { Link Here
2758
2756
2759
    # Send a renewal slip according to checkout alert preferencei
2757
    # Send a renewal slip according to checkout alert preferencei
2760
    if ( C4::Context->preference('RenewalSendNotice') eq '1') {
2758
    if ( C4::Context->preference('RenewalSendNotice') eq '1') {
2761
	my $borrower = C4::Members::GetMemberDetails( $borrowernumber, 0 );
2759
    my $borrower = C4::Members::GetMemberDetails( $borrowernumber, 0 );
2762
	my $circulation_alert = 'C4::ItemCirculationAlertPreference';
2760
    my $circulation_alert = 'C4::ItemCirculationAlertPreference';
2763
	my %conditions = (
2761
    my %conditions = (
2764
		branchcode   => $branch,
2762
        branchcode   => $branch,
2765
		categorycode => $borrower->{categorycode},
2763
        categorycode => $borrower->{categorycode},
2766
		item_type    => $item->{itype},
2764
        item_type    => $item->{itype},
2767
		notification => 'CHECKOUT',
2765
        notification => 'CHECKOUT',
2768
	);
2766
    );
2769
	if ($circulation_alert->is_enabled_for(\%conditions)) {
2767
    if ($circulation_alert->is_enabled_for(\%conditions)) {
2770
		SendCirculationAlert({
2768
        SendCirculationAlert({
2771
			type     => 'RENEWAL',
2769
            type     => 'RENEWAL',
2772
			item     => $item,
2770
            item     => $item,
2773
		borrower => $borrower,
2771
        borrower => $borrower,
2774
		branch   => $branch,
2772
        branch   => $branch,
2775
		});
2773
        });
2776
	}
2774
    }
2777
    }
2775
    }
2778
2776
2779
    # Remove any OVERDUES related debarment if the borrower has no overdues
2777
    # Remove any OVERDUES related debarment if the borrower has no overdues
Lines 2788-2794 sub AddRenewal { Link Here
2788
2786
2789
    # Log the renewal
2787
    # Log the renewal
2790
    UpdateStats( $branch, 'renew', $charge, '', $itemnumber, $item->{itype}, $borrowernumber, undef, $item->{'ccode'});
2788
    UpdateStats( $branch, 'renew', $charge, '', $itemnumber, $item->{itype}, $borrowernumber, undef, $item->{'ccode'});
2791
	return $datedue;
2789
    return $datedue;
2792
}
2790
}
2793
2791
2794
sub GetRenewCount {
2792
sub GetRenewCount {
Lines 2800-2806 sub GetRenewCount { Link Here
2800
    my $renewsleft    = 0;
2798
    my $renewsleft    = 0;
2801
2799
2802
    my $borrower = C4::Members::GetMember( borrowernumber => $bornum);
2800
    my $borrower = C4::Members::GetMember( borrowernumber => $bornum);
2803
    my $item     = GetItem($itemno); 
2801
    my $item     = GetItem($itemno);
2804
2802
2805
    # Look in the issues table for this item, lent to this borrower,
2803
    # Look in the issues table for this item, lent to this borrower,
2806
    # and not yet returned.
2804
    # and not yet returned.
Lines 2816-2824 sub GetRenewCount { Link Here
2816
    $renewcount = $data->{'renewals'} if $data->{'renewals'};
2814
    $renewcount = $data->{'renewals'} if $data->{'renewals'};
2817
    # $item and $borrower should be calculated
2815
    # $item and $borrower should be calculated
2818
    my $branchcode = _GetCircControlBranch($item, $borrower);
2816
    my $branchcode = _GetCircControlBranch($item, $borrower);
2819
    
2817
2820
    my $issuingrule = GetIssuingRule($borrower->{categorycode}, $item->{itype}, $branchcode);
2818
    my $issuingrule = GetIssuingRule($borrower->{categorycode}, $item->{itype}, $branchcode);
2821
    
2819
2822
    $renewsallowed = $issuingrule->{'renewalsallowed'};
2820
    $renewsallowed = $issuingrule->{'renewalsallowed'};
2823
    $renewsleft    = $renewsallowed - $renewcount;
2821
    $renewsleft    = $renewsallowed - $renewcount;
2824
    if($renewsleft < 0){ $renewsleft = 0; }
2822
    if($renewsleft < 0){ $renewsleft = 0; }
Lines 3151-3157 sub SendCirculationAlert { Link Here
3151
    my %message_name = (
3149
    my %message_name = (
3152
        CHECKIN  => 'Item_Check_in',
3150
        CHECKIN  => 'Item_Check_in',
3153
        CHECKOUT => 'Item_Checkout',
3151
        CHECKOUT => 'Item_Checkout',
3154
	RENEWAL  => 'Item_Checkout',
3152
    RENEWAL  => 'Item_Checkout',
3155
    );
3153
    );
3156
    my $borrower_preferences = C4::Members::Messaging::GetMessagingPreferences({
3154
    my $borrower_preferences = C4::Members::Messaging::GetMessagingPreferences({
3157
        borrowernumber => $borrower->{borrowernumber},
3155
        borrowernumber => $borrower->{borrowernumber},
Lines 3194-3218 sub SendCirculationAlert { Link Here
3194
3192
3195
  $items = updateWrongTransfer($itemNumber,$borrowernumber,$waitingAtLibrary,$FromLibrary);
3193
  $items = updateWrongTransfer($itemNumber,$borrowernumber,$waitingAtLibrary,$FromLibrary);
3196
3194
3197
This function validate the line of brachtransfer but with the wrong destination (mistake from a librarian ...), and create a new line in branchtransfer from the actual library to the original library of reservation 
3195
This function validate the line of brachtransfer but with the wrong destination (mistake from a librarian ...), and create a new line in branchtransfer from the actual library to the original library of reservation
3198
3196
3199
=cut
3197
=cut
3200
3198
3201
sub updateWrongTransfer {
3199
sub updateWrongTransfer {
3202
	my ( $itemNumber,$waitingAtLibrary,$FromLibrary ) = @_;
3200
    my ( $itemNumber,$waitingAtLibrary,$FromLibrary ) = @_;
3203
	my $dbh = C4::Context->dbh;	
3201
    my $dbh = C4::Context->dbh;
3204
# first step validate the actual line of transfert .
3202
# first step validate the actual line of transfert .
3205
	my $sth =
3203
    my $sth =
3206
        	$dbh->prepare(
3204
            $dbh->prepare(
3207
			"update branchtransfers set datearrived = now(),tobranch=?,comments='wrongtransfer' where itemnumber= ? AND datearrived IS NULL"
3205
            "update branchtransfers set datearrived = now(),tobranch=?,comments='wrongtransfer' where itemnumber= ? AND datearrived IS NULL"
3208
          	);
3206
              );
3209
        	$sth->execute($FromLibrary,$itemNumber);
3207
            $sth->execute($FromLibrary,$itemNumber);
3210
3208
3211
# second step create a new line of branchtransfer to the right location .
3209
# second step create a new line of branchtransfer to the right location .
3212
	ModItemTransfer($itemNumber, $FromLibrary, $waitingAtLibrary);
3210
    ModItemTransfer($itemNumber, $FromLibrary, $waitingAtLibrary);
3213
3211
3214
#third step changing holdingbranch of item
3212
#third step changing holdingbranch of item
3215
	UpdateHoldingbranch($FromLibrary,$itemNumber);
3213
    UpdateHoldingbranch($FromLibrary,$itemNumber);
3216
}
3214
}
3217
3215
3218
=head2 UpdateHoldingbranch
3216
=head2 UpdateHoldingbranch
Lines 3224-3230 Simple methode for updating hodlingbranch in items BDD line Link Here
3224
=cut
3222
=cut
3225
3223
3226
sub UpdateHoldingbranch {
3224
sub UpdateHoldingbranch {
3227
	my ( $branch,$itemnumber ) = @_;
3225
    my ( $branch,$itemnumber ) = @_;
3228
    ModItem({ holdingbranch => $branch }, undef, $itemnumber);
3226
    ModItem({ holdingbranch => $branch }, undef, $itemnumber);
3229
}
3227
}
3230
3228
Lines 3336-3352 This function checks if the date due is a repeatable holiday Link Here
3336
3334
3337
C<$date_due>   = returndate calculate with no day check
3335
C<$date_due>   = returndate calculate with no day check
3338
C<$itemnumber>  = itemnumber
3336
C<$itemnumber>  = itemnumber
3339
C<$branchcode>  = localisation of issue 
3337
C<$branchcode>  = localisation of issue
3340
3338
3341
=cut
3339
=cut
3342
3340
3343
sub CheckRepeatableHolidays{
3341
sub CheckRepeatableHolidays{
3344
my($itemnumber,$week_day,$branchcode)=@_;
3342
my($itemnumber,$week_day,$branchcode)=@_;
3345
my $dbh = C4::Context->dbh;
3343
my $dbh = C4::Context->dbh;
3346
my $query = qq|SELECT count(*)  
3344
my $query = qq|SELECT count(*)
3347
	FROM repeatable_holidays 
3345
    FROM repeatable_holidays
3348
	WHERE branchcode=?
3346
    WHERE branchcode=?
3349
	AND weekday=?|;
3347
    AND weekday=?|;
3350
my $sth = $dbh->prepare($query);
3348
my $sth = $dbh->prepare($query);
3351
$sth->execute($branchcode,$week_day);
3349
$sth->execute($branchcode,$week_day);
3352
my $result=$sth->fetchrow;
3350
my $result=$sth->fetchrow;
Lines 3364-3383 C<$years> = the years of datedue Link Here
3364
C<$month>   = the month of datedue
3362
C<$month>   = the month of datedue
3365
C<$day>     = the day of datedue
3363
C<$day>     = the day of datedue
3366
C<$itemnumber>  = itemnumber
3364
C<$itemnumber>  = itemnumber
3367
C<$branchcode>  = localisation of issue 
3365
C<$branchcode>  = localisation of issue
3368
3366
3369
=cut
3367
=cut
3370
3368
3371
sub CheckSpecialHolidays{
3369
sub CheckSpecialHolidays{
3372
my ($years,$month,$day,$itemnumber,$branchcode) = @_;
3370
my ($years,$month,$day,$itemnumber,$branchcode) = @_;
3373
my $dbh = C4::Context->dbh;
3371
my $dbh = C4::Context->dbh;
3374
my $query=qq|SELECT count(*) 
3372
my $query=qq|SELECT count(*)
3375
	     FROM `special_holidays`
3373
         FROM `special_holidays`
3376
	     WHERE year=?
3374
         WHERE year=?
3377
	     AND month=?
3375
         AND month=?
3378
	     AND day=?
3376
         AND day=?
3379
             AND branchcode=?
3377
             AND branchcode=?
3380
	    |;
3378
        |;
3381
my $sth = $dbh->prepare($query);
3379
my $sth = $dbh->prepare($query);
3382
$sth->execute($years,$month,$day,$branchcode);
3380
$sth->execute($years,$month,$day,$branchcode);
3383
my $countspecial=$sth->fetchrow ;
3381
my $countspecial=$sth->fetchrow ;
Lines 3393-3411 This function check if the date is a repeatble special holidays Link Here
3393
C<$month>   = the month of datedue
3391
C<$month>   = the month of datedue
3394
C<$day>     = the day of datedue
3392
C<$day>     = the day of datedue
3395
C<$itemnumber>  = itemnumber
3393
C<$itemnumber>  = itemnumber
3396
C<$branchcode>  = localisation of issue 
3394
C<$branchcode>  = localisation of issue
3397
3395
3398
=cut
3396
=cut
3399
3397
3400
sub CheckRepeatableSpecialHolidays{
3398
sub CheckRepeatableSpecialHolidays{
3401
my ($month,$day,$itemnumber,$branchcode) = @_;
3399
my ($month,$day,$itemnumber,$branchcode) = @_;
3402
my $dbh = C4::Context->dbh;
3400
my $dbh = C4::Context->dbh;
3403
my $query=qq|SELECT count(*) 
3401
my $query=qq|SELECT count(*)
3404
	     FROM `repeatable_holidays`
3402
         FROM `repeatable_holidays`
3405
	     WHERE month=?
3403
         WHERE month=?
3406
	     AND day=?
3404
         AND day=?
3407
             AND branchcode=?
3405
             AND branchcode=?
3408
	    |;
3406
        |;
3409
my $sth = $dbh->prepare($query);
3407
my $sth = $dbh->prepare($query);
3410
$sth->execute($month,$day,$branchcode);
3408
$sth->execute($month,$day,$branchcode);
3411
my $countspecial=$sth->fetchrow ;
3409
my $countspecial=$sth->fetchrow ;
Lines 3417-3426 return $countspecial; Link Here
3417
sub CheckValidBarcode{
3415
sub CheckValidBarcode{
3418
my ($barcode) = @_;
3416
my ($barcode) = @_;
3419
my $dbh = C4::Context->dbh;
3417
my $dbh = C4::Context->dbh;
3420
my $query=qq|SELECT count(*) 
3418
my $query=qq|SELECT count(*)
3421
	     FROM items 
3419
         FROM items
3422
             WHERE barcode=?
3420
             WHERE barcode=?
3423
	    |;
3421
        |;
3424
my $sth = $dbh->prepare($query);
3422
my $sth = $dbh->prepare($query);
3425
$sth->execute($barcode);
3423
$sth->execute($barcode);
3426
my $exist=$sth->fetchrow ;
3424
my $exist=$sth->fetchrow ;
Lines 3436-3459 Code is either an itemtype or collection doe depending on the pref BranchTransfe Link Here
3436
=cut
3434
=cut
3437
3435
3438
sub IsBranchTransferAllowed {
3436
sub IsBranchTransferAllowed {
3439
	my ( $toBranch, $fromBranch, $code ) = @_;
3437
    my ( $toBranch, $fromBranch, $code ) = @_;
3440
3438
3441
	if ( $toBranch eq $fromBranch ) { return 1; } ## Short circuit for speed.
3439
    if ( $toBranch eq $fromBranch ) { return 1; } ## Short circuit for speed.
3442
        
3440
3443
	my $limitType = C4::Context->preference("BranchTransferLimitsType");   
3441
    my $limitType = C4::Context->preference("BranchTransferLimitsType");
3444
	my $dbh = C4::Context->dbh;
3442
    my $dbh = C4::Context->dbh;
3445
            
3443
3446
	my $sth = $dbh->prepare("SELECT * FROM branch_transfer_limits WHERE toBranch = ? AND fromBranch = ? AND $limitType = ?");
3444
    my $sth = $dbh->prepare("SELECT * FROM branch_transfer_limits WHERE toBranch = ? AND fromBranch = ? AND $limitType = ?");
3447
	$sth->execute( $toBranch, $fromBranch, $code );
3445
    $sth->execute( $toBranch, $fromBranch, $code );
3448
	my $limit = $sth->fetchrow_hashref();
3446
    my $limit = $sth->fetchrow_hashref();
3449
                        
3447
3450
	## If a row is found, then that combination is not allowed, if no matching row is found, then the combination *is allowed*
3448
    ## If a row is found, then that combination is not allowed, if no matching row is found, then the combination *is allowed*
3451
	if ( $limit->{'limitId'} ) {
3449
    if ( $limit->{'limitId'} ) {
3452
		return 0;
3450
        return 0;
3453
	} else {
3451
    } else {
3454
		return 1;
3452
        return 1;
3455
	}
3453
    }
3456
}                                                        
3454
}
3457
3455
3458
=head2 CreateBranchTransferLimit
3456
=head2 CreateBranchTransferLimit
3459
3457
Lines 3467-3475 sub CreateBranchTransferLimit { Link Here
3467
   my ( $toBranch, $fromBranch, $code ) = @_;
3465
   my ( $toBranch, $fromBranch, $code ) = @_;
3468
   return unless defined($toBranch) && defined($fromBranch);
3466
   return unless defined($toBranch) && defined($fromBranch);
3469
   my $limitType = C4::Context->preference("BranchTransferLimitsType");
3467
   my $limitType = C4::Context->preference("BranchTransferLimitsType");
3470
   
3468
3471
   my $dbh = C4::Context->dbh;
3469
   my $dbh = C4::Context->dbh;
3472
   
3470
3473
   my $sth = $dbh->prepare("INSERT INTO branch_transfer_limits ( $limitType, toBranch, fromBranch ) VALUES ( ?, ?, ? )");
3471
   my $sth = $dbh->prepare("INSERT INTO branch_transfer_limits ( $limitType, toBranch, fromBranch ) VALUES ( ?, ?, ? )");
3474
   return $sth->execute( $code, $toBranch, $fromBranch );
3472
   return $sth->execute( $code, $toBranch, $fromBranch );
3475
}
3473
}
Lines 3510-3518 sub LostItem{ Link Here
3510
    my ($itemnumber, $mark_returned) = @_;
3508
    my ($itemnumber, $mark_returned) = @_;
3511
3509
3512
    my $dbh = C4::Context->dbh();
3510
    my $dbh = C4::Context->dbh();
3513
    my $sth=$dbh->prepare("SELECT issues.*,items.*,biblio.title 
3511
    my $sth=$dbh->prepare("SELECT issues.*,items.*,biblio.title
3514
                           FROM issues 
3512
                           FROM issues
3515
                           JOIN items USING (itemnumber) 
3513
                           JOIN items USING (itemnumber)
3516
                           JOIN biblio USING (biblionumber)
3514
                           JOIN biblio USING (biblionumber)
3517
                           WHERE issues.itemnumber=?");
3515
                           WHERE issues.itemnumber=?");
3518
    $sth->execute($itemnumber);
3516
    $sth->execute($itemnumber);
(-)a/installer/data/mysql/sysprefs.sql (-1 / +1 lines)
Lines 332-338 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
332
('RenewalPeriodBase','date_due','date_due|now','Set whether the renewal date should be counted from the date_due or from the moment the Patron asks for renewal ','Choice'),
332
('RenewalPeriodBase','date_due','date_due|now','Set whether the renewal date should be counted from the date_due or from the moment the Patron asks for renewal ','Choice'),
333
('RenewalSendNotice','0','',NULL,'YesNo'),
333
('RenewalSendNotice','0','',NULL,'YesNo'),
334
('RenewSerialAddsSuggestion','0',NULL,'If ON, adds a new suggestion at serial subscription renewal','YesNo'),
334
('RenewSerialAddsSuggestion','0',NULL,'If ON, adds a new suggestion at serial subscription renewal','YesNo'),
335
('RentalFeesCheckoutConfirmation', '1', NULL , 'Allow user to confirme when checking out an item with rental fees.', 'YesNo'),
335
('RentalFeesCheckoutConfirmation', '0', NULL , 'Allow user to confirme when checking out an item with rental fees.', 'YesNo'),
336
('RentalsInNoissuesCharge','1',NULL,'Rental charges block checkouts (added to noissuescharge).','YesNo'),
336
('RentalsInNoissuesCharge','1',NULL,'Rental charges block checkouts (added to noissuescharge).','YesNo'),
337
('RequestOnOpac','1',NULL,'If ON, globally enables patron holds on OPAC','YesNo'),
337
('RequestOnOpac','1',NULL,'If ON, globally enables patron holds on OPAC','YesNo'),
338
('ReservesControlBranch','PatronLibrary','ItemHomeLibrary|PatronLibrary','Branch checked for members reservations rights','Choice'),
338
('ReservesControlBranch','PatronLibrary','ItemHomeLibrary|PatronLibrary','Branch checked for members reservations rights','Choice'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt (-3 / +2 lines)
Lines 203-213 var MSG_EXPORT_SELECT_CHECKOUTS = _("You must select checkout(s) to export"); Link Here
203
[% END %]
203
[% END %]
204
204
205
[% IF ( DEBT ) %]
205
[% IF ( DEBT ) %]
206
    <li>The patron has a debt of [% DEBT %]</li>
206
    <li>The patron has a debt of [% DEBT %].</li>
207
[% END %]
207
[% END %]
208
208
209
[% IF ( RENTALCHARGE ) %]
209
[% IF ( RENTALCHARGE ) %]
210
    <li>Rental charge for this item : [% RENTALCHARGE %]</li>
210
    <li>Rental charge for this item: [% RENTALCHARGE %]</li>
211
[% END %]
211
[% END %]
212
212
213
[% IF ( RENEW_ISSUE ) %]
213
[% IF ( RENEW_ISSUE ) %]
214
- 

Return to bug 12448