Bugzilla – Attachment 31480 Details for
Bug 6427
Rewrite of the accounts system
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 6427 - Update existing Koha perl modules
Bug-6427---Update-existing-Koha-perl-modules.patch (text/plain), 58.36 KB, created by
Kyle M Hall (khall)
on 2014-09-09 12:49:28 UTC
(
hide
)
Description:
Bug 6427 - Update existing Koha perl modules
Filename:
MIME Type:
Creator:
Kyle M Hall (khall)
Created:
2014-09-09 12:49:28 UTC
Size:
58.36 KB
patch
obsolete
>From 57ad352271c590d27550ad3fcde1dc3fe6ae953d Mon Sep 17 00:00:00 2001 >From: Kyle M Hall <kyle@bywatersolutions.com> >Date: Tue, 15 Jul 2014 10:55:30 -0400 >Subject: [PATCH] Bug 6427 - Update existing Koha perl modules > >--- > C4/Circulation.pm | 413 +++++++++++++++--------------- > C4/ILSDI/Services.pm | 9 +- > C4/Members.pm | 188 ++++---------- > C4/Overdues.pm | 371 ++++++++++----------------- > C4/Reports/Guided.pm | 29 ++- > C4/Reserves.pm | 23 +- > C4/SIP/ILS/Patron.pm | 2 +- > C4/SIP/ILS/Transaction/FeePayment.pm | 19 +- > Koha/DateUtils.pm | 7 +- > Koha/Template/Plugin/AuthorisedValues.pm | 2 + > Koha/Template/Plugin/Koha.pm | 5 + > 11 files changed, 462 insertions(+), 606 deletions(-) > >diff --git a/C4/Circulation.pm b/C4/Circulation.pm >index 55f0c27..7c737f6 100644 >--- a/C4/Circulation.pm >+++ b/C4/Circulation.pm >@@ -30,7 +30,8 @@ use C4::Items; > use C4::Members; > use C4::Dates; > use C4::Dates qw(format_date); >-use C4::Accounts; >+use Koha::Accounts; >+use Koha::Accounts::CreditTypes; > use C4::ItemCirculationAlertPreference; > use C4::Message; > use C4::Debug; >@@ -48,6 +49,7 @@ use Data::Dumper; > use Koha::DateUtils; > use Koha::Calendar; > use Koha::Borrower::Debarments; >+use Koha::Database; > use Carp; > use Date::Calc qw( > Today >@@ -1280,7 +1282,7 @@ sub AddIssue { > ## If item was lost, it has now been found, reverse any list item charges if neccessary. > if ( $item->{'itemlost'} ) { > if ( C4::Context->preference('RefundLostItemFeeOnReturn' ) ) { >- _FixAccountForLostAndReturned( $item->{'itemnumber'}, undef, $item->{'barcode'} ); >+ _FixAccountForLostAndReturned( $item->{'itemnumber'} ); > } > } > >@@ -1845,21 +1847,32 @@ sub AddReturn { > > $type ||= q{}; > >- if ( C4::Context->preference('finesMode') eq 'production' ) { >- if ( $amount > 0 ) { >- C4::Overdues::UpdateFine( $issue->{itemnumber}, >- $issue->{borrowernumber}, >- $amount, $type, output_pref($datedue) ); >- } >- elsif ($return_date) { >- >- # Backdated returns may have fines that shouldn't exist, >- # so in this case, we need to drop those fines to 0 >- >- C4::Overdues::UpdateFine( $issue->{itemnumber}, >- $issue->{borrowernumber}, >- 0, $type, output_pref($datedue) ); >- } >+ if ( $amount > 0 >+ && C4::Context->preference('finesMode') eq 'production' ) >+ { >+ C4::Overdues::UpdateFine( >+ { >+ itemnumber => $issue->{itemnumber}, >+ borrowernumber => $issue->{borrowernumber}, >+ amount => $amount, >+ due => output_pref($datedue), >+ issue_id => $issue->{issue_id} >+ } >+ ); >+ } >+ elsif ($return_date) { >+ >+ # Backdated returns may have fines that shouldn't exist, >+ # so in this case, we need to drop those fines to 0 >+ C4::Overdues::UpdateFine( >+ { >+ itemnumber => $issue->{itemnumber}, >+ borrowernumber => $issue->{borrowernumber}, >+ amount => 0, >+ due => output_pref($datedue), >+ issue_id => $issue->{issue_id} >+ } >+ ); > } > } > >@@ -1909,15 +1922,20 @@ sub AddReturn { > $messages->{'WasLost'} = 1; > > if ( C4::Context->preference('RefundLostItemFeeOnReturn' ) ) { >- _FixAccountForLostAndReturned($item->{'itemnumber'}, $borrowernumber, $barcode); # can tolerate undef $borrowernumber >+ _FixAccountForLostAndReturned( $item->{'itemnumber'} ); > $messages->{'LostItemFeeRefunded'} = 1; > } > } > > # fix up the overdues in accounts... > if ($borrowernumber) { >- my $fix = _FixOverduesOnReturn($borrowernumber, $item->{itemnumber}, $exemptfine, $dropbox); >- defined($fix) or warn "_FixOverduesOnReturn($borrowernumber, $item->{itemnumber}...) failed!"; # zero is OK, check defined >+ _FinalizeFine( >+ { >+ exempt_fine => $exemptfine, >+ dropbox => $dropbox, >+ issue => Koha::Database->new()->schema->resultset('OldIssue')->find( $issue->{issue_id} ), >+ } >+ ); > > if ( $issue->{overdue} && $issue->{date_due} ) { > # fix fine days >@@ -2026,10 +2044,6 @@ of the return. It is ignored when a dropbox_branch is passed in. > C<$privacy> contains the privacy parameter. If the patron has set privacy to 2, > the old_issue is immediately anonymised > >-Ideally, this function would be internal to C<C4::Circulation>, >-not exported, but it is currently needed by one >-routine in C<C4::Accounts>. >- > =cut > > sub MarkIssueReturned { >@@ -2151,155 +2165,129 @@ sub _debar_user_on_return { > return; > } > >-=head2 _FixOverduesOnReturn >- >- &_FixOverduesOnReturn($brn,$itm, $exemptfine, $dropboxmode); >- >-C<$brn> borrowernumber >+=head2 _FinalizeFine > >-C<$itm> itemnumber >+ _FinalizeFine({ >+ exempt_fine => $exempt_fine, >+ dropbox => $dropbox, >+ issue => $issue, >+ }); > > C<$exemptfine> BOOL -- remove overdue charge associated with this issue. > C<$dropboxmode> BOOL -- remove lastincrement on overdue charge associated with this issue. >+C<$issue> -- DBIx::Class::Row for the issue > >-Internal function, called only by AddReturn >+This subrouting closes out the accuruing of a fine, and reduces if it exemptfine or >+dropbox flags are passed in. > > =cut > >-sub _FixOverduesOnReturn { >- my ($borrowernumber, $item); >- unless ($borrowernumber = shift) { >- warn "_FixOverduesOnReturn() not supplied valid borrowernumber"; >- return; >- } >- unless ($item = shift) { >- warn "_FixOverduesOnReturn() not supplied valid itemnumber"; >- return; >- } >- my ($exemptfine, $dropbox) = @_; >+sub _FinalizeFine { >+ my ( $params ) = @_; >+ >+ my $exemptfine = $params->{exempt_fine}; >+ my $dropbox = $params->{dropbox}; >+ my $issue = $params->{issue}; >+ > my $dbh = C4::Context->dbh; > >- # check for overdue fine >- my $sth = $dbh->prepare( >-"SELECT * FROM accountlines WHERE (borrowernumber = ?) AND (itemnumber = ?) AND (accounttype='FU' OR accounttype='O')" >+ my $schema = Koha::Database->new()->schema; >+ my $fine = $schema->resultset('AccountDebit')->single( >+ { >+ issue_id => $issue->issue_id(), >+ type => Koha::Accounts::DebitTypes::Fine(), >+ accruing => 1, >+ } > ); >- $sth->execute( $borrowernumber, $item ); > >- # alter fine to show that the book has been returned >- my $data = $sth->fetchrow_hashref; >- return 0 unless $data; # no warning, there's just nothing to fix >+ return unless ( $fine ); >+ >+ $fine->accruing(0); > >- my $uquery; >- my @bind = ($data->{'accountlines_id'}); > if ($exemptfine) { >- $uquery = "update accountlines set accounttype='FFOR', amountoutstanding=0"; >- if (C4::Context->preference("FinesLog")) { >- &logaction("FINES", 'MODIFY',$borrowernumber,"Overdue forgiven: item $item"); >- } >- } elsif ($dropbox && $data->{lastincrement}) { >- my $outstanding = $data->{amountoutstanding} - $data->{lastincrement} ; >- my $amt = $data->{amount} - $data->{lastincrement} ; >+ AddCredit( >+ { >+ borrower => $fine->borrowernumber(), >+ amount => $fine->amount_original(), >+ debit_id => $fine->debit_id(), >+ type => Koha::Accounts::CreditTypes::Forgiven(), >+ } >+ ); > if (C4::Context->preference("FinesLog")) { >- &logaction("FINES", 'MODIFY',$borrowernumber,"Dropbox adjustment $amt, item $item"); >- } >- $uquery = "update accountlines set accounttype='F' "; >- if($outstanding >= 0 && $amt >=0) { >- $uquery .= ", amount = ? , amountoutstanding=? "; >- unshift @bind, ($amt, $outstanding) ; >+ &logaction( >+ "FINES", 'MODIFY', >+ $issue->{borrowernumber}, >+ "Overdue forgiven: item " . $issue->{itemnumber} >+ ); > } >- } else { >- $uquery = "update accountlines set accounttype='F' "; >+ } elsif ($dropbox && $fine->amount_last_increment() != $fine->amount_original() ) { >+ if ( C4::Context->preference("FinesLog") ) { >+ &logaction( "FINES", 'MODIFY', $issue->{borrowernumber}, >+ "Dropbox adjustment " >+ . $fine->amount_last_increment() >+ . ", item " . $issue->{itemnumber} ); >+ } >+ $fine->amount_original( >+ $fine->amount_original() - $fine->amount_last_increment() ); >+ $fine->amount_outstanding( >+ $fine->amount_outstanding - $fine->amount_last_increment() ); >+ $schema->resultset('AccountOffset')->create( >+ { >+ debit_id => $fine->debit_id(), >+ type => Koha::Accounts::OffsetTypes::Dropbox(), >+ amount => $fine->amount_last_increment() * -1, >+ } >+ ); > } >- $uquery .= " where (accountlines_id = ?)"; >- my $usth = $dbh->prepare($uquery); >- return $usth->execute(@bind); >+ >+ return $fine->update(); > } > > =head2 _FixAccountForLostAndReturned > >- &_FixAccountForLostAndReturned($itemnumber, [$borrowernumber, $barcode]); >- >-Calculates the charge for a book lost and returned. >- >-Internal function, not exported, called only by AddReturn. >+ &_FixAccountForLostAndReturned($itemnumber); > >-FIXME: This function reflects how inscrutable fines logic is. Fix both. >-FIXME: Give a positive return value on success. It might be the $borrowernumber who received credit, or the amount forgiven. >+ Refunds a lost item fee in necessary > > =cut > > sub _FixAccountForLostAndReturned { >- my $itemnumber = shift or return; >- my $borrowernumber = @_ ? shift : undef; >- my $item_id = @_ ? shift : $itemnumber; # Send the barcode if you want that logged in the description >- my $dbh = C4::Context->dbh; >- # check for charge made for lost book >- my $sth = $dbh->prepare("SELECT * FROM accountlines WHERE itemnumber = ? AND accounttype IN ('L', 'Rep', 'W') ORDER BY date DESC, accountno DESC"); >- $sth->execute($itemnumber); >- my $data = $sth->fetchrow_hashref; >- $data or return; # bail if there is nothing to do >- $data->{accounttype} eq 'W' and return; # Written off >- >- # writeoff this amount >- my $offset; >- my $amount = $data->{'amount'}; >- my $acctno = $data->{'accountno'}; >- my $amountleft; # Starts off undef/zero. >- if ($data->{'amountoutstanding'} == $amount) { >- $offset = $data->{'amount'}; >- $amountleft = 0; # Hey, it's zero here, too. >- } else { >- $offset = $amount - $data->{'amountoutstanding'}; # Um, isn't this the same as ZERO? We just tested those two things are == >- $amountleft = $data->{'amountoutstanding'} - $amount; # Um, isn't this the same as ZERO? We just tested those two things are == >- } >- my $usth = $dbh->prepare("UPDATE accountlines SET accounttype = 'LR',amountoutstanding='0' >- WHERE (accountlines_id = ?)"); >- $usth->execute($data->{'accountlines_id'}); # We might be adjusting an account for some OTHER borrowernumber now. Not the one we passed in. >- #check if any credit is left if so writeoff other accounts >- my $nextaccntno = getnextacctno($data->{'borrowernumber'}); >- $amountleft *= -1 if ($amountleft < 0); >- if ($amountleft > 0) { >- my $msth = $dbh->prepare("SELECT * FROM accountlines WHERE (borrowernumber = ?) >- AND (amountoutstanding >0) ORDER BY date"); # might want to order by amountoustanding ASC (pay smallest first) >- $msth->execute($data->{'borrowernumber'}); >- # offset transactions >- my $newamtos; >- my $accdata; >- while (($accdata=$msth->fetchrow_hashref) and ($amountleft>0)){ >- if ($accdata->{'amountoutstanding'} < $amountleft) { >- $newamtos = 0; >- $amountleft -= $accdata->{'amountoutstanding'}; >- } else { >- $newamtos = $accdata->{'amountoutstanding'} - $amountleft; >- $amountleft = 0; >- } >- my $thisacct = $accdata->{'accountlines_id'}; >- # FIXME: move prepares outside while loop! >- my $usth = $dbh->prepare("UPDATE accountlines SET amountoutstanding= ? >- WHERE (accountlines_id = ?)"); >- $usth->execute($newamtos,$thisacct); >- $usth = $dbh->prepare("INSERT INTO accountoffsets >- (borrowernumber, accountno, offsetaccount, offsetamount) >- VALUES >- (?,?,?,?)"); >- $usth->execute($data->{'borrowernumber'},$accdata->{'accountno'},$nextaccntno,$newamtos); >- } >- } >- $amountleft *= -1 if ($amountleft > 0); >- my $desc = "Item Returned " . $item_id; >- $usth = $dbh->prepare("INSERT INTO accountlines >- (borrowernumber,accountno,date,amount,description,accounttype,amountoutstanding) >- VALUES (?,?,now(),?,?,'CR',?)"); >- $usth->execute($data->{'borrowernumber'},$nextaccntno,0-$amount,$desc,$amountleft); >- if ($borrowernumber) { >- # FIXME: same as query above. use 1 sth for both >- $usth = $dbh->prepare("INSERT INTO accountoffsets >- (borrowernumber, accountno, offsetaccount, offsetamount) >- VALUES (?,?,?,?)"); >- $usth->execute($borrowernumber, $data->{'accountno'}, $nextaccntno, $offset); >- } >+ my ( $itemnumber ) = @_; >+ >+ my $schema = Koha::Database->new()->schema; >+ >+ # Find the last issue for this item >+ my $issue = >+ $schema->resultset('Issue')->single( { itemnumber => $itemnumber } ); >+ $issue ||= >+ $schema->resultset('OldIssue')->single( { itemnumber => $itemnumber } ); >+ >+ return unless $issue; >+ >+ # Find a lost fee for this issue >+ my $debit = $schema->resultset('AccountDebit')->single( >+ { >+ issue_id => $issue->issue_id(), >+ type => Koha::Accounts::DebitTypes::Lost() >+ } >+ ); >+ >+ return unless $debit; >+ >+ # Check for an existing found credit for this debit, if there is one, the fee has already been refunded and we do nothing >+ my @credits = $debit->account_offsets->search_related('credit', { 'credit.type' => Koha::Accounts::CreditTypes::Found() }); >+ >+ return if @credits; >+ >+ # Ok, so we know we have an unrefunded lost item fee, let's refund it >+ CreditLostItem( >+ { >+ borrower => $issue->borrower(), >+ debit => $debit >+ } >+ ); >+ > ModItem({ paidfor => '' }, undef, $itemnumber); >- return; > } > > =head2 _GetCircControlBranch >@@ -2698,14 +2686,11 @@ sub AddRenewal { > my $dbh = C4::Context->dbh; > > # Find the issues record for this book >- my $sth = >- $dbh->prepare("SELECT * FROM issues WHERE itemnumber = ?"); >- $sth->execute( $itemnumber ); >- my $issuedata = $sth->fetchrow_hashref; >+ my $issue = Koha::Database->new()->schema->resultset('Issue')->single({ itemnumber => $itemnumber }); > >- return unless ( $issuedata ); >+ return unless ( $issue ); > >- $borrowernumber ||= $issuedata->{borrowernumber}; >+ $borrowernumber ||= $issue->get_column('borrowernumber'); > > if ( defined $datedue && ref $datedue ne 'DateTime' ) { > carp 'Invalid date passed to AddRenewal.'; >@@ -2721,41 +2706,45 @@ sub AddRenewal { > my $itemtype = (C4::Context->preference('item-level_itypes')) ? $biblio->{'itype'} : $biblio->{'itemtype'}; > > $datedue = (C4::Context->preference('RenewalPeriodBase') eq 'date_due') ? >- dt_from_string( $issuedata->{date_due} ) : >+ dt_from_string( $issue->get_column('date_due') ) : > DateTime->now( time_zone => C4::Context->tz()); >- $datedue = CalcDateDue($datedue, $itemtype, $issuedata->{'branchcode'}, $borrower, 'is a renewal'); >+ $datedue = CalcDateDue($datedue, $itemtype, $issue->get_column('branchcode'), $borrower, 'is a renewal'); > } > > # Update the issues record to have the new due date, and a new count > # of how many times it has been renewed. >- my $renews = $issuedata->{'renewals'} + 1; >- $sth = $dbh->prepare("UPDATE issues SET date_due = ?, renewals = ?, lastreneweddate = ? >- WHERE borrowernumber=? >- AND itemnumber=?" >+ $issue->update( >+ { >+ date_due => $datedue->strftime('%Y-%m-%d %H:%M'), >+ renewals => $issue->renewals() + 1, >+ lastreneweddate => $lastreneweddate, >+ } > ); > >- $sth->execute( $datedue->strftime('%Y-%m-%d %H:%M'), $renews, $lastreneweddate, $borrowernumber, $itemnumber ); > > # Update the renewal count on the item, and tell zebra to reindex >- $renews = $biblio->{'renewals'} + 1; >+ my $renews = $biblio->{'renewals'} + 1; > ModItem({ renewals => $renews, onloan => $datedue->strftime('%Y-%m-%d %H:%M')}, $biblio->{'biblionumber'}, $itemnumber); > > # Charge a new rental fee, if applicable? > my ( $charge, $type ) = GetIssuingCharges( $itemnumber, $borrowernumber ); > if ( $charge > 0 ) { >- my $accountno = getnextacctno( $borrowernumber ); > my $item = GetBiblioFromItemNumber($itemnumber); >- my $manager_id = 0; >- $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv; >- $sth = $dbh->prepare( >- "INSERT INTO accountlines >- (date, borrowernumber, accountno, amount, manager_id, >- description,accounttype, amountoutstanding, itemnumber) >- VALUES (now(),?,?,?,?,?,?,?,?)" >+ >+ my $borrower = >+ Koha::Database->new()->schema->resultset('Borrower') >+ ->find($borrowernumber); >+ >+ AddDebit( >+ { >+ borrower => $borrower, >+ itemnumber => $itemnumber, >+ amount => $charge, >+ type => Koha::Accounts::DebitTypes::Rental(), >+ description => >+ "Renewal of Rental Item $item->{'title'} $item->{'barcode'}" >+ } > ); >- $sth->execute( $borrowernumber, $accountno, $charge, $manager_id, >- "Renewal of Rental Item $item->{'title'} $item->{'barcode'}", >- 'Rent', $charge, $itemnumber ); > } > > # Send a renewal slip according to checkout alert preferencei >@@ -2797,6 +2786,9 @@ sub AddRenewal { > borrowernumber => $borrowernumber, > ccode => $item->{'ccode'}} > ); >+ >+ _FinalizeFine( { issue => $issue } ); >+ > return $datedue; > } > >@@ -2981,25 +2973,21 @@ sub _get_discount_from_rule { > > =head2 AddIssuingCharge > >- &AddIssuingCharge( $itemno, $borrowernumber, $charge ) >+ &AddIssuingCharge( $itemnumber, $borrowernumber, $amount ) > > =cut > > sub AddIssuingCharge { >- my ( $itemnumber, $borrowernumber, $charge ) = @_; >- my $dbh = C4::Context->dbh; >- my $nextaccntno = getnextacctno( $borrowernumber ); >- my $manager_id = 0; >- $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv; >- my $query =" >- INSERT INTO accountlines >- (borrowernumber, itemnumber, accountno, >- date, amount, description, accounttype, >- amountoutstanding, manager_id) >- VALUES (?, ?, ?,now(), ?, 'Rental', 'Rent',?,?) >- "; >- my $sth = $dbh->prepare($query); >- $sth->execute( $borrowernumber, $itemnumber, $nextaccntno, $charge, $charge, $manager_id ); >+ my ( $itemnumber, $borrowernumber, $amount ) = @_; >+ >+ return AddDebit( >+ { >+ borrower => Koha::Database->new()->schema->resultset('Borrower')->find($borrowernumber), >+ itemnumber => $itemnumber, >+ amount => $amount, >+ type => Koha::Accounts::DebitTypes::Rental(), >+ } >+ ); > } > > =head2 GetTransfers >@@ -3518,30 +3506,34 @@ sub ReturnLostItem{ > sub LostItem{ > my ($itemnumber, $mark_returned) = @_; > >- my $dbh = C4::Context->dbh(); >- my $sth=$dbh->prepare("SELECT issues.*,items.*,biblio.title >- FROM issues >- JOIN items USING (itemnumber) >- JOIN biblio USING (biblionumber) >- WHERE issues.itemnumber=?"); >- $sth->execute($itemnumber); >- my $issues=$sth->fetchrow_hashref(); >+ my $schema = Koha::Database->new()->schema; > >- # If a borrower lost the item, add a replacement cost to the their record >- if ( my $borrowernumber = $issues->{borrowernumber} ){ >- my $borrower = C4::Members::GetMemberDetails( $borrowernumber ); >+ my $issue = >+ $schema->resultset('Issue')->single( { itemnumber => $itemnumber } ); > >+ my ( $borrower, $item ); >+ >+ if ( $issue ) { >+ $borrower = $issue->borrower(); >+ $item = $issue->item(); >+ } >+ >+ # If a borrower lost the item, add a replacement cost to the their record >+ if ( $borrower ){ > if (C4::Context->preference('WhenLostForgiveFine')){ >- my $fix = _FixOverduesOnReturn($borrowernumber, $itemnumber, 1, 0); # 1, 0 = exemptfine, no-dropbox >- defined($fix) or warn "_FixOverduesOnReturn($borrowernumber, $itemnumber...) failed!"; # zero is OK, check defined >+ _FinalizeFine( >+ { >+ exempt_fine => 1, >+ dropbox => 0, >+ issue => $issue, >+ } >+ ); > } >- if (C4::Context->preference('WhenLostChargeReplacementFee')){ >- C4::Accounts::chargelostitem($borrowernumber, $itemnumber, $issues->{'replacementprice'}, "Lost Item $issues->{'title'} $issues->{'barcode'}"); >- #FIXME : Should probably have a way to distinguish this from an item that really was returned. >- #warn " $issues->{'borrowernumber'} / $itemnumber "; >+ if ( C4::Context->preference('WhenLostChargeReplacementFee') ) { >+ DebitLostItem( { borrower => $borrower, issue => $issue } ); > } > >- MarkIssueReturned($borrowernumber,$itemnumber,undef,undef,$borrower->{'privacy'}) if $mark_returned; >+ MarkIssueReturned( $borrower->borrowernumber(), $item->itemnumber(), undef, undef, $borrower->privacy() ) if $mark_returned; > } > } > >@@ -3659,10 +3651,15 @@ sub ProcessOfflineIssue { > sub ProcessOfflinePayment { > my $operation = shift; > >- my $borrower = C4::Members::GetMemberDetails( undef, $operation->{cardnumber} ); # Get borrower from operation cardnumber >- my $amount = $operation->{amount}; >- >- recordpayment( $borrower->{borrowernumber}, $amount ); >+ AddCredit( >+ { >+ borrower => Koha::Database->new()->schema->resultset('Borrower') >+ ->single( { cardnumber => $operation->{cardnumber} } ), >+ amount => $operation->{amount}, >+ notes => 'via offline circulation', >+ type => Koha::Accounts::CreditTypes::Payment, >+ } >+ ); > > return "Success." > } >diff --git a/C4/ILSDI/Services.pm b/C4/ILSDI/Services.pm >index bd201d3..ce2fc17 100644 >--- a/C4/ILSDI/Services.pm >+++ b/C4/ILSDI/Services.pm >@@ -24,7 +24,6 @@ use C4::Members; > use C4::Items; > use C4::Circulation; > use C4::Branch; >-use C4::Accounts; > use C4::Biblio; > use C4::Reserves qw(AddReserve CancelReserve GetReservesFromBiblionumber GetReservesFromBorrowernumber CanBookBeReserved CanItemBeReserved); > use C4::Context; >@@ -34,6 +33,7 @@ use HTML::Entities; > use CGI; > use DateTime; > use C4::Auth; >+use Koha::Database; > > =head1 NAME > >@@ -387,10 +387,9 @@ sub GetPatronInfo { > > # Fines management > if ( $cgi->param('show_fines') eq "1" ) { >- my @charges; >- for ( my $i = 1 ; my @charge = getcharges( $borrowernumber, undef, $i ) ; $i++ ) { >- push( @charges, @charge ); >- } >+ my @charges = >+ Koha::Database->new()->schema()->resultset('AccountDebit') >+ ->search( { borrowernumber => $borrowernumber } ); > $borrower->{'fines'}->{'fine'} = \@charges; > } > >diff --git a/C4/Members.pm b/C4/Members.pm >index e3a5538..5787fb4 100644 >--- a/C4/Members.pm >+++ b/C4/Members.pm >@@ -29,7 +29,6 @@ use Date::Calc qw/Today Add_Delta_YM check_date Date_to_Days/; > use C4::Log; # logaction > use C4::Overdues; > use C4::Reserves; >-use C4::Accounts; > use C4::Biblio; > use C4::Letters; > use C4::SQLHelper qw(InsertInTable UpdateInTable SearchInTable); >@@ -42,6 +41,7 @@ use Koha::Borrower::Debarments qw(IsDebarred); > use Text::Unaccent qw( unac_string ); > use Koha::AuthUtils qw(hash_password); > use Koha::Database; >+use Koha::Accounts::DebitTypes; > > our ($VERSION,@ISA,@EXPORT,@EXPORT_OK,$debug); > >@@ -81,8 +81,6 @@ BEGIN { > &GetHideLostItemsPreference > > &IsMemberBlocked >- &GetMemberAccountRecords >- &GetBorNotifyAcctRecord > > &GetborCatFromCatType > &GetBorrowercategory >@@ -356,9 +354,8 @@ sub GetMemberDetails { > } > my $borrower = $sth->fetchrow_hashref; > return unless $borrower; >- my ($amount) = GetMemberAccountRecords( $borrowernumber); >- $borrower->{'amountoutstanding'} = $amount; >- # FIXME - patronflags calls GetMemberAccountRecords... just have patronflags return $amount >+ $borrower->{amountoutstanding} = $borrower->{account_balance}; >+ # FIXME - find all references to $borrower->{amountoutstanding}, replace with $borrower->{account_balance} > my $flags = patronflags( $borrower); > my $accessflagshash; > >@@ -462,23 +459,20 @@ The "message" field that comes from the DB is OK. > # FIXME rename this function. > sub patronflags { > my %flags; >- my ( $patroninformation) = @_; >- my $dbh=C4::Context->dbh; >- my ($balance, $owing) = GetMemberAccountBalance( $patroninformation->{'borrowernumber'}); >- if ( $owing > 0 ) { >+ my ($patroninformation) = @_; >+ my $dbh = C4::Context->dbh; >+ if ( $patroninformation->{account_balance} > 0 ) { > my %flaginfo; > my $noissuescharge = C4::Context->preference("noissuescharge") || 5; >- $flaginfo{'message'} = sprintf 'Patron owes %.02f', $owing; >- $flaginfo{'amount'} = sprintf "%.02f", $owing; >- if ( $owing > $noissuescharge && !C4::Context->preference("AllowFineOverride") ) { >+ $flaginfo{'amount'} = $patroninformation->{account_balance}; >+ if ( $patroninformation->{account_balance} > $noissuescharge && !C4::Context->preference("AllowFineOverride") ) { > $flaginfo{'noissues'} = 1; > } > $flags{'CHARGES'} = \%flaginfo; > } >- elsif ( $balance < 0 ) { >+ elsif ( $patroninformation->{account_balance} < 0 ) { > my %flaginfo; >- $flaginfo{'message'} = sprintf 'Patron has credit of %.02f', -$balance; >- $flaginfo{'amount'} = sprintf "%.02f", $balance; >+ $flaginfo{'amount'} = $patroninformation->{account_balance}; > $flags{'CREDITS'} = \%flaginfo; > } > if ( $patroninformation->{'gonenoaddress'} >@@ -721,7 +715,7 @@ sub GetMemberIssuesAndFines { > $sth->execute($borrowernumber); > my $overdue_count = $sth->fetchrow_arrayref->[0]; > >- $sth = $dbh->prepare("SELECT SUM(amountoutstanding) FROM accountlines WHERE borrowernumber = ?"); >+ $sth = $dbh->prepare("SELECT account_balance FROM borrowers WHERE borrowernumber = ?"); > $sth->execute($borrowernumber); > my $total_fines = $sth->fetchrow_arrayref->[0]; > >@@ -1210,57 +1204,14 @@ sub GetAllIssues { > } > > >-=head2 GetMemberAccountRecords >- >- ($total, $acctlines, $count) = &GetMemberAccountRecords($borrowernumber); >- >-Looks up accounting data for the patron with the given borrowernumber. >- >-C<&GetMemberAccountRecords> returns a three-element array. C<$acctlines> is a >-reference-to-array, where each element is a reference-to-hash; the >-keys are the fields of the C<accountlines> table in the Koha database. >-C<$count> is the number of elements in C<$acctlines>. C<$total> is the >-total amount outstanding for all of the account lines. >- >-=cut >- >-sub GetMemberAccountRecords { >- my ($borrowernumber) = @_; >- my $dbh = C4::Context->dbh; >- my @acctlines; >- my $numlines = 0; >- my $strsth = qq( >- SELECT * >- FROM accountlines >- WHERE borrowernumber=?); >- $strsth.=" ORDER BY date desc,timestamp DESC"; >- my $sth= $dbh->prepare( $strsth ); >- $sth->execute( $borrowernumber ); >- >- my $total = 0; >- while ( my $data = $sth->fetchrow_hashref ) { >- if ( $data->{itemnumber} ) { >- my $biblio = GetBiblioFromItemNumber( $data->{itemnumber} ); >- $data->{biblionumber} = $biblio->{biblionumber}; >- $data->{title} = $biblio->{title}; >- } >- $acctlines[$numlines] = $data; >- $numlines++; >- $total += int(1000 * $data->{'amountoutstanding'}); # convert float to integer to avoid round-off errors >- } >- $total /= 1000; >- return ( $total, \@acctlines,$numlines); >-} >- > =head2 GetMemberAccountBalance > > ($total_balance, $non_issue_balance, $other_charges) = &GetMemberAccountBalance($borrowernumber); > > Calculates amount immediately owing by the patron - non-issue charges. >-Based on GetMemberAccountRecords. > Charges exempt from non-issue are: >-* Res (reserves) >-* Rent (rental) if RentalsInNoissuesCharge syspref is set to false >+* HOLD fees (reserves) >+* RENTAL if RentalsInNoissuesCharge syspref is set to false > * Manual invoices if ManInvInNoissuesCharge syspref is set to false > > =cut >@@ -1268,71 +1219,41 @@ Charges exempt from non-issue are: > sub GetMemberAccountBalance { > my ($borrowernumber) = @_; > >- my $ACCOUNT_TYPE_LENGTH = 5; # this is plain ridiculous... >+ my $borrower = >+ Koha::Database->new()->schema->resultset('Borrower') >+ ->find($borrowernumber); > > my @not_fines; >- push @not_fines, 'Res' unless C4::Context->preference('HoldsInNoissuesCharge'); >- push @not_fines, 'Rent' unless C4::Context->preference('RentalsInNoissuesCharge'); >- unless ( C4::Context->preference('ManInvInNoissuesCharge') ) { >- my $dbh = C4::Context->dbh; >- my $man_inv_types = $dbh->selectcol_arrayref(qq{SELECT authorised_value FROM authorised_values WHERE category = 'MANUAL_INV'}); >- push @not_fines, map substr($_, 0, $ACCOUNT_TYPE_LENGTH), @$man_inv_types; >- } >- my %not_fine = map {$_ => 1} @not_fines; >- >- my ($total, $acctlines) = GetMemberAccountRecords($borrowernumber); >- my $other_charges = 0; >- foreach (@$acctlines) { >- $other_charges += $_->{amountoutstanding} if $not_fine{ substr($_->{accounttype}, 0, $ACCOUNT_TYPE_LENGTH) }; >- } >- >- return ( $total, $total - $other_charges, $other_charges); >-} > >-=head2 GetBorNotifyAcctRecord >+ push( @not_fines, Koha::Accounts::DebitTypes::Hold() ); > >- ($total, $acctlines, $count) = &GetBorNotifyAcctRecord($params,$notifyid); >+ push( @not_fines, Koha::Accounts::DebitTypes::Rental() ) >+ unless C4::Context->preference('RentalsInNoissuesCharge'); > >-Looks up accounting data for the patron with the given borrowernumber per file number. >- >-C<&GetBorNotifyAcctRecord> returns a three-element array. C<$acctlines> is a >-reference-to-array, where each element is a reference-to-hash; the >-keys are the fields of the C<accountlines> table in the Koha database. >-C<$count> is the number of elements in C<$acctlines>. C<$total> is the >-total amount outstanding for all of the account lines. >- >-=cut >+ unless ( C4::Context->preference('ManInvInNoissuesCharge') ) { >+ my $dbh = C4::Context->dbh; >+ my $man_inv_types = $dbh->selectcol_arrayref(q{ >+ SELECT authorised_value FROM authorised_values WHERE category = 'MANUAL_INV' >+ }); >+ push( @not_fines, @$man_inv_types ); >+ } > >-sub GetBorNotifyAcctRecord { >- my ( $borrowernumber, $notifyid ) = @_; >- my $dbh = C4::Context->dbh; >- my @acctlines; >- my $numlines = 0; >- my $sth = $dbh->prepare( >- "SELECT * >- FROM accountlines >- WHERE borrowernumber=? >- AND notify_id=? >- AND amountoutstanding != '0' >- ORDER BY notify_id,accounttype >- "); >- >- $sth->execute( $borrowernumber, $notifyid ); >- my $total = 0; >- while ( my $data = $sth->fetchrow_hashref ) { >- if ( $data->{itemnumber} ) { >- my $biblio = GetBiblioFromItemNumber( $data->{itemnumber} ); >- $data->{biblionumber} = $biblio->{biblionumber}; >- $data->{title} = $biblio->{title}; >+ my $other_charges = >+ Koha::Database->new()->schema->resultset('AccountDebit')->search( >+ { >+ borrowernumber => $borrowernumber, >+ type => { -in => \@not_fines } > } >- $acctlines[$numlines] = $data; >- $numlines++; >- $total += int(100 * $data->{'amountoutstanding'}); >- } >- $total /= 100; >- return ( $total, \@acctlines, $numlines ); >+ )->get_column('amount_outstanding')->sum(); >+ >+ return ( >+ $borrower->account_balance(), >+ $borrower->account_balance() - $other_charges, >+ $other_charges >+ ); > } > >+ > =head2 checkuniquemember (OUEST-PROVENCE) > > ($result,$categorycode) = &checkuniquemember($collectivity,$surname,$firstname,$dateofbirth); >@@ -2463,22 +2384,21 @@ Add enrolment fee for a patron if needed. > > sub AddEnrolmentFeeIfNeeded { > my ( $categorycode, $borrowernumber ) = @_; >- # check for enrollment fee & add it if needed >- my $dbh = C4::Context->dbh; >- my $sth = $dbh->prepare(q{ >- SELECT enrolmentfee >- FROM categories >- WHERE categorycode=? >- }); >- $sth->execute( $categorycode ); >- if ( $sth->err ) { >- warn sprintf('Database returned the following error: %s', $sth->errstr); >- return; >- } >- my ($enrolmentfee) = $sth->fetchrow; >- if ($enrolmentfee && $enrolmentfee > 0) { >- # insert fee in patron debts >- C4::Accounts::manualinvoice( $borrowernumber, '', '', 'A', $enrolmentfee ); >+ >+ my $schema = Koha::Database->new()->schema(); >+ >+ my $category = $schema->resultset('Category')->find($categorycode); >+ my $fee = $category->enrolmentfee(); >+ >+ if ( $fee && $fee > 0 ) { >+ AddDebit( >+ { >+ borrower => >+ $schema->resultset('Borrower')->find($borrowernumber), >+ type => Koha::Accounts::DebitTypes::AccountManagementFee(), >+ amount => $fee, >+ } >+ ); > } > } > >diff --git a/C4/Overdues.pm b/C4/Overdues.pm >index 31314d6..26f454a 100644 >--- a/C4/Overdues.pm >+++ b/C4/Overdues.pm >@@ -27,9 +27,12 @@ use List::MoreUtils qw( uniq ); > > use C4::Circulation; > use C4::Context; >-use C4::Accounts; > use C4::Log; # logaction > use C4::Debug; >+use Koha::Database; >+use Koha::DateUtils; >+use Koha::Accounts::OffsetTypes; >+use Koha::Accounts::DebitTypes; > > use vars qw($VERSION @ISA @EXPORT); > >@@ -43,12 +46,9 @@ BEGIN { > &CalcFine > &Getoverdues > &checkoverdues >- &NumberNotifyId >- &AmountNotify > &UpdateFine > &GetFine > >- &CheckItemNotify > &GetOverduesForBranch > &RemoveNotifyLine > &AddNotifyLine >@@ -463,154 +463,143 @@ sub GetIssuesIteminfo { > > =head2 UpdateFine > >- &UpdateFine($itemnumber, $borrowernumber, $amount, $type, $description); >+ UpdateFine( >+ { >+ itemnumber => $itemnumber, >+ borrowernumber => $borrowernumber, >+ amount => $amount, >+ due => $due, >+ issue_id => $issue_id >+ } >+ ); > >-(Note: the following is mostly conjecture and guesswork.) >+Updates the fine owed on an overdue item. > >-Updates the fine owed on an overdue book. >+C<$itemnumber> is the items's id. > >-C<$itemnumber> is the book's item number. >+C<$borrowernumber> is the id of the patron who currently >+has the item on loan. > >-C<$borrowernumber> is the borrower number of the patron who currently >-has the book on loan. >+C<$amount> is the total amount of the fine owed by the patron. > >-C<$amount> is the current amount owed by the patron. >+C<&UpdateFine> updates the amount owed for a given fine if an issue_id >+is passed to it. Otherwise, a new fine will be created. > >-C<$type> will be used in the description of the fine. >+=cut > >-C<$description> is a string that must be present in the description of >-the fine. I think this is expected to be a date in DD/MM/YYYY format. >+sub UpdateFine { >+ my ($params) = @_; > >-C<&UpdateFine> looks up the amount currently owed on the given item >-and sets it to C<$amount>, creating, if necessary, a new entry in the >-accountlines table of the Koha database. >+ my $itemnumber = $params->{itemnumber}; >+ my $borrowernumber = $params->{borrowernumber}; >+ my $amount = $params->{amount}; >+ my $due = $params->{due}; >+ my $issue_id = $params->{issue_id}; > >-=cut >+ my $schema = Koha::Database->new()->schema; > >-# >-# Question: Why should the caller have to >-# specify both the item number and the borrower number? A book can't >-# be on loan to two different people, so the item number should be >-# sufficient. >-# >-# Possible Answer: You might update a fine for a damaged item, *after* it is returned. >-# >-sub UpdateFine { >- my ( $itemnum, $borrowernumber, $amount, $type, $due ) = @_; >- $debug and warn "UpdateFine($itemnum, $borrowernumber, $amount, " . ($type||'""') . ", $due) called"; >- my $dbh = C4::Context->dbh; >- # FIXME - What exactly is this query supposed to do? It looks up an >- # entry in accountlines that matches the given item and borrower >- # numbers, where the description contains $due, and where the >- # account type has one of several values, but what does this _mean_? >- # Does it look up existing fines for this item? >- # FIXME - What are these various account types? ("FU", "O", "F", "M") >- # "L" is LOST item >- # "A" is Account Management Fee >- # "N" is New Card >- # "M" is Sundry >- # "O" is Overdue ?? >- # "F" is Fine ?? >- # "FU" is Fine UPDATE?? >- # "Pay" is Payment >- # "REF" is Cash Refund >- my $sth = $dbh->prepare( >- "SELECT * FROM accountlines >- WHERE borrowernumber=? >- AND accounttype IN ('FU','O','F','M')" >- ); >- $sth->execute( $borrowernumber ); >- my $data; >- my $total_amount_other = 0.00; >- my $due_qr = qr/$due/; >- # Cycle through the fines and >- # - find line that relates to the requested $itemnum >- # - accumulate fines for other items >- # so we can update $itemnum fine taking in account fine caps >- while (my $rec = $sth->fetchrow_hashref) { >- if ($rec->{itemnumber} == $itemnum && $rec->{description} =~ /$due_qr/) { >- if ($data) { >- warn "Not a unique accountlines record for item $itemnum borrower $borrowernumber"; >- } else { >- $data = $rec; >- next; >+ my $borrower = $schema->resultset('Borrower')->find($borrowernumber); >+ >+ if ( my $maxfine = C4::Context->preference('MaxFine') ) { >+ if ( $borrower->account_balance() + $amount > $maxfine ) { >+ my $new_amount = $maxfine - $borrower->account_balance(); >+ warn "Reducing fine for item $itemnumber borrower $borrowernumber from $amount to $new_amount - MaxFine reached"; >+ if ( $new_amount <= 0 ) { >+ warn "Fine reduced to a non-positive ammount. Fine not created."; >+ return; > } >+ $amount = $new_amount; > } >- $total_amount_other += $rec->{'amountoutstanding'}; > } > >- if (my $maxfine = C4::Context->preference('MaxFine')) { >- if ($total_amount_other + $amount > $maxfine) { >- my $new_amount = $maxfine - $total_amount_other; >- return if $new_amount <= 0.00; >- warn "Reducing fine for item $itemnum borrower $borrowernumber from $amount to $new_amount - MaxFine reached"; >- $amount = $new_amount; >+ my $timestamp = get_timestamp(); >+ >+ my $fine = $schema->resultset('AccountDebit')->single( >+ { >+ issue_id => $issue_id, >+ type => Koha::Accounts::DebitTypes::Fine, >+ accruing => 1, > } >- } >+ ); > >- if ( $data ) { >- >- # we're updating an existing fine. Only modify if amount changed >- # Note that in the current implementation, you cannot pay against an accruing fine >- # (i.e. , of accounttype 'FU'). Doing so will break accrual. >- if ( $data->{'amount'} != $amount ) { >- my $diff = $amount - $data->{'amount'}; >- #3341: diff could be positive or negative! >- my $out = $data->{'amountoutstanding'} + $diff; >- my $query = " >- UPDATE accountlines >- SET date=now(), amount=?, amountoutstanding=?, >- lastincrement=?, accounttype='FU' >- WHERE borrowernumber=? >- AND itemnumber=? >- AND accounttype IN ('FU','O') >- AND description LIKE ? >- LIMIT 1 "; >- my $sth2 = $dbh->prepare($query); >- # FIXME: BOGUS query cannot ensure uniqueness w/ LIKE %x% !!! >- # LIMIT 1 added to prevent multiple affected lines >- # FIXME: accountlines table needs unique key!! Possibly a combo of borrowernumber and accountline. >- # But actually, we should just have a regular autoincrementing PK and forget accountline, >- # including the bogus getnextaccountno function (doesn't prevent conflict on simultaneous ops). >- # FIXME: Why only 2 account types here? >- $debug and print STDERR "UpdateFine query: $query\n" . >- "w/ args: $amount, $out, $diff, $data->{'borrowernumber'}, $data->{'itemnumber'}, \"\%$due\%\"\n"; >- $sth2->execute($amount, $out, $diff, $data->{'borrowernumber'}, $data->{'itemnumber'}, "%$due%"); >- } else { >- # print "no update needed $data->{'amount'}" >+ my $offset = 0; >+ my $credit; >+ if ($fine) { >+ if ( $fine->accruing() ) { # Don't update or recreate fines no longer accruing >+ if ( >+ sprintf( "%.6f", $fine->amount_original() ) >+ ne >+ sprintf( "%.6f", $amount ) ) >+ { >+ my $difference = $amount - $fine->amount_original(); >+ >+ # Fine was reduced by a change in circulation rules or another reason >+ # we need to credit the account the difference and zero out the amount outstanding >+ if ( $difference < 0 ) { >+ $fine->amount_outstanding( $fine->amount_outstanding() + $difference ); >+ >+ $credit = >+ Koha::Database->new()->schema->resultset('AccountCredit') >+ ->create( >+ { >+ borrowernumber => $borrowernumber, >+ type => Koha::Accounts::CreditTypes::FineReduction(), >+ amount_remaining => abs($difference), >+ created_on => $timestamp, >+ } >+ ); >+ >+ } else { >+ $fine->amount_outstanding( 0 ); >+ } >+ >+ $fine->amount_last_increment($difference); >+ $fine->amount_original( $fine->amount_original() + $difference ); >+ $fine->updated_on($timestamp); >+ $fine->update(); >+ >+ $offset = 1; >+ } > } >- } else { >- my $sth4 = $dbh->prepare( >- "SELECT title FROM biblio LEFT JOIN items ON biblio.biblionumber=items.biblionumber WHERE items.itemnumber=?" >+ } >+ else { >+ my $item = $schema->resultset('Item')->find($itemnumber); >+ >+ $fine = $schema->resultset('AccountDebit')->create( >+ { >+ borrowernumber => $borrowernumber, >+ itemnumber => $itemnumber, >+ issue_id => $issue_id, >+ type => Koha::Accounts::DebitTypes::Fine(), >+ accruing => 1, >+ amount_original => $amount, >+ amount_outstanding => $amount, >+ amount_last_increment => $amount, >+ description => $item->biblio()->title() . " / Due:$due", >+ created_on => $timestamp, >+ } > ); >- $sth4->execute($itemnum); >- my $title = $sth4->fetchrow; >- >-# # print "not in account"; >-# my $sth3 = $dbh->prepare("Select max(accountno) from accountlines"); >-# $sth3->execute; >-# >-# # FIXME - Make $accountno a scalar. >-# my @accountno = $sth3->fetchrow_array; >-# $sth3->finish; >-# $accountno[0]++; >-# begin transaction >- my $nextaccntno = C4::Accounts::getnextacctno($borrowernumber); >- my $desc = ($type ? "$type " : '') . "$title $due"; # FIXEDME, avoid whitespace prefix on empty $type >- my $query = "INSERT INTO accountlines >- (borrowernumber,itemnumber,date,amount,description,accounttype,amountoutstanding,lastincrement,accountno) >- VALUES (?,?,now(),?,?,'FU',?,?,?)"; >- my $sth2 = $dbh->prepare($query); >- $debug and print STDERR "UpdateFine query: $query\nw/ args: $borrowernumber, $itemnum, $amount, $desc, $amount, $amount, $nextaccntno\n"; >- $sth2->execute($borrowernumber, $itemnum, $amount, $desc, $amount, $amount, $nextaccntno); >+ >+ $offset = 1; > } >- # logging action >- &logaction( >- "FINES", >- $type, >+ >+ $schema->resultset('AccountOffset')->create( >+ { >+ debit_id => $fine->debit_id(), >+ credit_id => $credit ? $credit->credit_id() : undef, >+ amount => $fine->amount_last_increment(), >+ created_on => $timestamp, >+ type => Koha::Accounts::OffsetTypes::Fine(), >+ } >+ ) if $offset; >+ >+ $borrower->account_balance( $borrower->account_balance + $fine->amount_last_increment() ); >+ $borrower->update(); >+ >+ logaction( "FINES", Koha::Accounts::DebitTypes::Fine(), > $borrowernumber, >- "due=".$due." amount=".$amount." itemnumber=".$itemnum >- ) if C4::Context->preference("FinesLog"); >+ "due=" . $due . " amount=" . $amount . " itemnumber=" . $itemnumber ) >+ if C4::Context->preference("FinesLog"); > } > > =head2 BorType >@@ -651,70 +640,19 @@ C<$borrowernumber> is the borrowernumber > =cut > > sub GetFine { >- my ( $itemnum, $borrowernumber ) = @_; >- my $dbh = C4::Context->dbh(); >- my $query = q|SELECT sum(amountoutstanding) as fineamount FROM accountlines >- where accounttype like 'F%' >- AND amountoutstanding > 0 AND itemnumber = ? AND borrowernumber=?|; >- my $sth = $dbh->prepare($query); >- $sth->execute( $itemnum, $borrowernumber ); >- my $fine = $sth->fetchrow_hashref(); >- if ($fine->{fineamount}) { >- return $fine->{fineamount}; >- } >- return 0; >-} >- >-=head2 NumberNotifyId >- >- (@notify) = &NumberNotifyId($borrowernumber); >- >-Returns amount for all file per borrowers >-C<@notify> array contains all file per borrowers >- >-C<$notify_id> contains the file number for the borrower number nad item number >- >-=cut >- >-sub NumberNotifyId{ >- my ($borrowernumber)=@_; >- my $dbh = C4::Context->dbh; >- my $query=qq| SELECT distinct(notify_id) >- FROM accountlines >- WHERE borrowernumber=?|; >- my @notify; >- my $sth = $dbh->prepare($query); >- $sth->execute($borrowernumber); >- while ( my ($numberofnotify) = $sth->fetchrow ) { >- push( @notify, $numberofnotify ); >- } >- return (@notify); >-} >+ my ( $itemnumber, $borrowernumber ) = @_; > >-=head2 AmountNotify >+ my $schema = Koha::Database->new()->schema; > >- ($totalnotify) = &AmountNotify($notifyid); >+ my $amount_outstanding = $schema->resultset('AccountDebit')->search( >+ { >+ itemnumber => $itemnumber, >+ borrowernumber => $borrowernumber, >+ type => Koha::Accounts::DebitTypes::Fine(), >+ }, >+ )->get_column('amount_outstanding')->sum(); > >-Returns amount for all file per borrowers >-C<$notifyid> is the file number >- >-C<$totalnotify> contains amount of a file >- >-C<$notify_id> contains the file number for the borrower number and item number >- >-=cut >- >-sub AmountNotify{ >- my ($notifyid,$borrowernumber)=@_; >- my $dbh = C4::Context->dbh; >- my $query=qq| SELECT sum(amountoutstanding) >- FROM accountlines >- WHERE notify_id=? AND borrowernumber = ?|; >- my $sth=$dbh->prepare($query); >- $sth->execute($notifyid,$borrowernumber); >- my $totalnotify=$sth->fetchrow; >- $sth->finish; >- return ($totalnotify); >+ return $amount_outstanding; > } > > =head2 GetItems >@@ -770,27 +708,6 @@ sub GetBranchcodesWithOverdueRules { > return @$branchcodes; > } > >-=head2 CheckItemNotify >- >-Sql request to check if the document has alreday been notified >-this function is not exported, only used with GetOverduesForBranch >- >-=cut >- >-sub CheckItemNotify { >- my ($notify_id,$notify_level,$itemnumber) = @_; >- my $dbh = C4::Context->dbh; >- my $sth = $dbh->prepare(" >- SELECT COUNT(*) >- FROM notifys >- WHERE notify_id = ? >- AND notify_level = ? >- AND itemnumber = ? "); >- $sth->execute($notify_id,$notify_level,$itemnumber); >- my $notified = $sth->fetchrow; >- return ($notified); >-} >- > =head2 GetOverduesForBranch > > Sql request for display all information for branchoverdues.pl >@@ -816,6 +733,7 @@ sub GetOverduesForBranch { > biblio.title, > biblio.author, > biblio.biblionumber, >+ issues.issue_id, > issues.date_due, > issues.returndate, > issues.branchcode, >@@ -826,25 +744,23 @@ sub GetOverduesForBranch { > items.location, > items.itemnumber, > itemtypes.description, >- accountlines.notify_id, >- accountlines.notify_level, >- accountlines.amountoutstanding >- FROM accountlines >- LEFT JOIN issues ON issues.itemnumber = accountlines.itemnumber >- AND issues.borrowernumber = accountlines.borrowernumber >- LEFT JOIN borrowers ON borrowers.borrowernumber = accountlines.borrowernumber >+ account_debits.amount_outstanding >+ FROM account_debits >+ LEFT JOIN issues ON issues.itemnumber = account_debits.itemnumber >+ AND issues.borrowernumber = account_debits.borrowernumber >+ LEFT JOIN borrowers ON borrowers.borrowernumber = account_debits.borrowernumber > LEFT JOIN items ON items.itemnumber = issues.itemnumber > LEFT JOIN biblio ON biblio.biblionumber = items.biblionumber > LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber > LEFT JOIN itemtypes ON itemtypes.itemtype = $itype_link > LEFT JOIN branches ON branches.branchcode = issues.branchcode >- WHERE (accountlines.amountoutstanding != '0.000000') >- AND (accountlines.accounttype = 'FU' ) >+ WHERE (account_debits.amount_outstanding != '0.000000') >+ AND (account_debits.type = 'FINE') >+ AND (account_debits.accruing = 1 ) > AND (issues.branchcode = ? ) > AND (issues.date_due < NOW()) > "; > my @getoverdues; >- my $i = 0; > my $sth; > if ($location) { > $sth = $dbh->prepare("$select AND items.location = ? ORDER BY borrowers.surname, borrowers.firstname"); >@@ -854,12 +770,7 @@ sub GetOverduesForBranch { > $sth->execute($branch); > } > while ( my $data = $sth->fetchrow_hashref ) { >- #check if the document has already been notified >- my $countnotify = CheckItemNotify($data->{'notify_id'}, $data->{'notify_level'}, $data->{'itemnumber'}); >- if ($countnotify eq '0') { >- $getoverdues[$i] = $data; >- $i++; >- } >+ push( @getoverdues, $data ); > } > return (@getoverdues); > } >diff --git a/C4/Reports/Guided.pm b/C4/Reports/Guided.pm >index a4c7c01..bec84c4 100644 >--- a/C4/Reports/Guided.pm >+++ b/C4/Reports/Guided.pm >@@ -92,18 +92,27 @@ my %table_areas = ( > CAT => [ 'items', 'biblioitems', 'biblio' ], > PAT => ['borrowers'], > ACQ => [ 'aqorders', 'biblio', 'items' ], >- ACC => [ 'borrowers', 'accountlines' ], >+ ACC => [ 'borrowers', 'account_credits', 'account_debits' ], > ); > my %keys = ( >- CIRC => [ 'statistics.borrowernumber=borrowers.borrowernumber', >- 'items.itemnumber = statistics.itemnumber', >- 'biblioitems.biblioitemnumber = items.biblioitemnumber' ], >- CAT => [ 'items.biblioitemnumber=biblioitems.biblioitemnumber', >- 'biblioitems.biblionumber=biblio.biblionumber' ], >- PAT => [], >- ACQ => [ 'aqorders.biblionumber=biblio.biblionumber', >- 'biblio.biblionumber=items.biblionumber' ], >- ACC => ['borrowers.borrowernumber=accountlines.borrowernumber'], >+ CIRC => [ >+ 'statistics.borrowernumber=borrowers.borrowernumber', >+ 'items.itemnumber = statistics.itemnumber', >+ 'biblioitems.biblioitemnumber = items.biblioitemnumber' >+ ], >+ CAT => [ >+ 'items.biblioitemnumber=biblioitems.biblioitemnumber', >+ 'biblioitems.biblionumber=biblio.biblionumber' >+ ], >+ PAT => [], >+ ACQ => [ >+ 'aqorders.biblionumber=biblio.biblionumber', >+ 'biblio.biblionumber=items.biblionumber' >+ ], >+ ACC => [ >+ 'borrowers.borrowernumber=account_credits.borrowernumber', >+ 'borrowers.borrowernumber=account_debits.borrowernumber' >+ ], > ); > > # have to do someting here to know if its dropdown, free text, date etc >diff --git a/C4/Reserves.pm b/C4/Reserves.pm >index d7cc334..06877ed 100644 >--- a/C4/Reserves.pm >+++ b/C4/Reserves.pm >@@ -28,7 +28,6 @@ use C4::Biblio; > use C4::Members; > use C4::Items; > use C4::Circulation; >-use C4::Accounts; > > # for _koha_notify_reserve > use C4::Members::Messaging; >@@ -173,19 +172,17 @@ sub AddReserve { > $waitingdate = $resdate; > } > >- #eval { >- # updates take place here > if ( $fee > 0 ) { >- my $nextacctno = &getnextacctno( $borrowernumber ); >- my $query = qq/ >- INSERT INTO accountlines >- (borrowernumber,accountno,date,amount,description,accounttype,amountoutstanding) >- VALUES >- (?,?,now(),?,?,'Res',?) >- /; >- my $usth = $dbh->prepare($query); >- $usth->execute( $borrowernumber, $nextacctno, $fee, >- "Reserve Charge - $title", $fee ); >+ AddDebit( >+ { >+ borrowernumber => $borrowernumber, >+ itemnumber => $checkitem, >+ amount => $fee, >+ type => Koha::Accounts::DebitTypes::Hold(), >+ description => "Hold fee - $title", >+ notes => "Record ID: $biblionumber", >+ } >+ ); > } > > #if ($const eq 'a'){ >diff --git a/C4/SIP/ILS/Patron.pm b/C4/SIP/ILS/Patron.pm >index 4ccd21b..cebc32a 100644 >--- a/C4/SIP/ILS/Patron.pm >+++ b/C4/SIP/ILS/Patron.pm >@@ -85,7 +85,7 @@ sub new { > hold_ok => ( !$debarred && !$expired ), > card_lost => ( $kp->{lost} || $kp->{gonenoaddress} || $flags->{LOST} ), > claims_returned => 0, >- fines => $fines_amount, # GetMemberAccountRecords($kp->{borrowernumber}) >+ fines => $fines_amount, > fees => 0, # currently not distinct from fines > recall_overdue => 0, > items_billed => 0, >diff --git a/C4/SIP/ILS/Transaction/FeePayment.pm b/C4/SIP/ILS/Transaction/FeePayment.pm >index ac6a3bc..a34505f 100644 >--- a/C4/SIP/ILS/Transaction/FeePayment.pm >+++ b/C4/SIP/ILS/Transaction/FeePayment.pm >@@ -20,7 +20,9 @@ use strict; > # with Koha; if not, write to the Free Software Foundation, Inc., > # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > >-use C4::Accounts qw(recordpayment); >+use Koha::Accounts qw(AddCredit); >+use Koha::Accounts::CreditTypes; >+use Koha::Database; > use ILS; > use parent qw(ILS::Transaction); > >@@ -45,10 +47,19 @@ sub new { > sub pay { > my $self = shift; > my $borrowernumber = shift; >- my $amt = shift; >+ my $amount = shift; > my $type = shift; >- warn("RECORD:$borrowernumber::$amt"); >- recordpayment( $borrowernumber, $amt,$type ); >+ >+ warn("RECORD:$borrowernumber::$amount"); >+ >+ AddCredit( >+ { >+ borrower => Koha::Database->new()->schema->resultset('Borrower')->find($borrowernumber), >+ amount => $amount, >+ notes => "via SIP2. Type:$type", >+ type => Koha::Accounts::CreditTypes::Payment, >+ } >+ ); > } > > #sub DESTROY { >diff --git a/Koha/DateUtils.pm b/Koha/DateUtils.pm >index b372a3a..384d62f 100644 >--- a/Koha/DateUtils.pm >+++ b/Koha/DateUtils.pm >@@ -21,13 +21,14 @@ use warnings; > use 5.010; > use DateTime; > use DateTime::Format::DateParse; >+use DateTime::Format::MySQL; > use C4::Context; > > use base 'Exporter'; > use version; our $VERSION = qv('1.0.0'); > > our @EXPORT = ( >- qw( dt_from_string output_pref format_sqldatetime ) >+ qw( dt_from_string output_pref format_sqldatetime get_timestamp ) > ); > > =head1 DateUtils >@@ -190,4 +191,8 @@ sub format_sqldatetime { > return q{}; > } > >+sub get_timestamp { >+ return DateTime::Format::MySQL->format_datetime( dt_from_string() ); >+} >+ > 1; >diff --git a/Koha/Template/Plugin/AuthorisedValues.pm b/Koha/Template/Plugin/AuthorisedValues.pm >index 65abac7..a1c160b 100644 >--- a/Koha/Template/Plugin/AuthorisedValues.pm >+++ b/Koha/Template/Plugin/AuthorisedValues.pm >@@ -74,3 +74,5 @@ Kyle M Hall <kyle@bywatersolutions.com> > Jonathan Druart <jonathan.druart@biblibre.com> > > =cut >+ >+1; >diff --git a/Koha/Template/Plugin/Koha.pm b/Koha/Template/Plugin/Koha.pm >index 2eff9f1..1212455 100644 >--- a/Koha/Template/Plugin/Koha.pm >+++ b/Koha/Template/Plugin/Koha.pm >@@ -44,4 +44,9 @@ sub Preference { > return C4::Context->preference( $pref ); > } > >+sub Get { >+ my ( $self, $category, $selected, $opac ) = @_; >+ return GetAuthorisedValues( $category, $selected, $opac ); >+} >+ > 1; >-- >1.7.2.5
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 6427
:
21922
|
22704
|
22705
|
22708
|
22709
|
22710
|
22741
|
22870
|
22871
|
22872
|
22873
|
22874
|
22875
|
22876
|
22881
|
22889
|
22940
|
22948
|
22949
|
22995
|
23000
|
23137
|
23158
|
23161
|
23171
|
23186
|
23269
|
23275
|
23276
|
23391
|
23392
|
23400
|
23401
|
23402
|
23403
|
23404
|
23405
|
23406
|
23407
|
23408
|
23409
|
23410
|
23411
|
23412
|
23413
|
23420
|
23421
|
23422
|
23423
|
23424
|
23425
|
23426
|
23427
|
23428
|
23429
|
23430
|
23431
|
23432
|
23433
|
23440
|
23441
|
23442
|
23443
|
23444
|
23445
|
23446
|
23447
|
23448
|
23449
|
23450
|
23451
|
23452
|
23453
|
23454
|
23458
|
23459
|
23460
|
23461
|
23462
|
23463
|
23464
|
23465
|
23466
|
23467
|
23468
|
23469
|
23470
|
23471
|
23603
|
23643
|
23644
|
23645
|
23646
|
23647
|
23648
|
23649
|
23650
|
23651
|
23652
|
23653
|
23654
|
23655
|
23656
|
23657
|
23937
|
23938
|
23939
|
23940
|
23941
|
23942
|
23943
|
23944
|
23945
|
23946
|
23947
|
23948
|
23949
|
23950
|
23951
|
24612
|
24613
|
24614
|
24615
|
24616
|
24617
|
24618
|
24619
|
24620
|
24621
|
24622
|
24623
|
24624
|
24625
|
24626
|
24627
|
24628
|
24757
|
24758
|
24759
|
24760
|
24761
|
24762
|
24763
|
24764
|
24765
|
24766
|
24767
|
24768
|
24769
|
24770
|
24771
|
24772
|
24777
|
24792
|
24793
|
24794
|
24795
|
24796
|
24797
|
24798
|
24799
|
24800
|
24801
|
24802
|
24803
|
24804
|
24805
|
24806
|
24807
|
24808
|
24809
|
24810
|
24811
|
24812
|
24813
|
24814
|
24815
|
24816
|
24817
|
24818
|
24819
|
24820
|
24821
|
24822
|
24823
|
24824
|
24825
|
24826
|
24827
|
24828
|
24829
|
24830
|
24831
|
24832
|
24833
|
24834
|
24835
|
24836
|
24837
|
24838
|
24839
|
24840
|
24841
|
24842
|
24843
|
24844
|
25777
|
25778
|
25779
|
25780
|
25781
|
25782
|
25783
|
25784
|
25785
|
25786
|
25787
|
25788
|
25789
|
25790
|
25791
|
25792
|
25793
|
25794
|
25795
|
25796
|
25797
|
25798
|
25799
|
25800
|
25801
|
25802
|
25803
|
25804
|
25805
|
25806
|
25807
|
25808
|
25809
|
25810
|
25811
|
25812
|
25813
|
25814
|
25815
|
25816
|
25930
|
25932
|
25933
|
25934
|
26033
|
26034
|
26035
|
26036
|
26107
|
27167
|
27168
|
27169
|
27170
|
27171
|
27172
|
27173
|
27174
|
27175
|
27176
|
27177
|
27178
|
27179
|
27180
|
27181
|
27182
|
27183
|
27184
|
27185
|
27186
|
27187
|
27189
|
27190
|
27197
|
28067
|
28068
|
28069
|
28070
|
28071
|
28072
|
28073
|
28074
|
28075
|
28076
|
28077
|
28078
|
28079
|
28080
|
28081
|
28082
|
28083
|
28084
|
28085
|
28086
|
28087
|
28088
|
28089
|
28090
|
28091
|
28527
|
28528
|
28529
|
28530
|
28531
|
28532
|
28533
|
28534
|
28535
|
28536
|
28537
|
28538
|
28539
|
28540
|
28541
|
28542
|
28543
|
28544
|
28545
|
28546
|
28547
|
28548
|
28549
|
28550
|
28551
|
28552
|
28553
|
28555
|
28556
|
28561
|
28563
|
28564
|
28795
|
28796
|
28797
|
28798
|
28799
|
28800
|
28801
|
28802
|
28803
|
28804
|
28805
|
28806
|
28807
|
28808
|
28809
|
28810
|
28811
|
28812
|
28813
|
28814
|
28815
|
28816
|
28817
|
28818
|
28819
|
28820
|
28821
|
28822
|
28887
|
28888
|
28889
|
28890
|
28909
|
29176
|
29230
|
29231
|
29232
|
29233
|
29234
|
29235
|
29236
|
29237
|
29238
|
29239
|
29240
|
29241
|
29242
|
29243
|
29244
|
29245
|
29246
|
29247
|
29248
|
29249
|
29250
|
29251
|
29252
|
29253
|
29254
|
29255
|
29256
|
29257
|
29258
|
29259
|
29260
|
29261
|
29262
|
29263
|
29264
|
29265
|
29706
|
29707
|
29708
|
29709
|
29710
|
29711
|
29712
|
29713
|
29714
|
29715
|
29716
|
29717
|
29719
|
29720
|
29721
|
29722
|
29723
|
29724
|
29725
|
29726
|
29727
|
29728
|
29729
|
29730
|
30271
|
30272
|
30273
|
30274
|
30275
|
30276
|
30277
|
30278
|
30279
|
30280
|
30281
|
30282
|
30320
|
30321
|
30322
|
30323
|
30324
|
30325
|
30326
|
30327
|
30328
|
30329
|
30330
|
30331
|
30416
|
30417
|
30418
|
30419
|
30420
|
30421
|
30422
|
30423
|
30424
|
30425
|
30426
|
30427
|
31477
|
31478
|
31479
|
31480
|
31481
|
31482
|
31483
|
31484
|
31485
|
31486
|
31487
|
31488
|
31754
|
31755
|
31756
|
31757
|
31758
|
31759
|
31760
|
31761
|
31762
|
31763
|
31764
|
31765
|
31766
|
31767
|
31768
|
31769
|
31770
|
31771
|
31772
|
31773
|
31774
|
31775
|
31776
|
31777
|
32478
|
32479
|
32480
|
32481
|
32482
|
32483
|
32484
|
32485
|
32486
|
32487
|
32488
|
32489
|
32591
|
32592
|
32593
|
32594
|
32595
|
32596
|
32597
|
32598
|
32599
|
32600
|
32601
|
32602
|
32827
|
32828
|
32829
|
32830
|
32831
|
32832
|
32833
|
32834
|
32835
|
32836
|
32837
|
32838
|
33251
|
33252
|
33253
|
33254
|
33255
|
33256
|
33257
|
33258
|
33259
|
33260
|
33261
|
33262
|
34096
|
34097
|
34098
|
34099
|
34100
|
34101
|
34102
|
34103
|
34104
|
34105
|
34106
|
34107
|
34204
|
34205
|
34206
|
34207
|
34208
|
34209
|
34210
|
34211
|
34212
|
34213
|
34214
|
34215
|
35196
|
35197
|
35198
|
35199
|
35200
|
35201
|
35202
|
35203
|
35204
|
35205
|
35206
|
35207
|
35208
|
35302
|
36324
|
36326
|
36327
|
36328
|
36329
|
36330
|
36331
|
36332
|
36333
|
36334
|
36335
|
36337
|
36338
|
36340
|
36380
|
36391
|
36393
|
37127
|
37128
|
37129
|
37130
|
37131
|
37133
|
37134
|
37135
|
37136
|
37137
|
37138
|
37139
|
37140
|
37141
|
37142
|
37143
|
37147
|
37148
|
37149
|
37150
|
37151
|
37152
|
37153
|
37154
|
37155
|
37156
|
37157
|
37158
|
37159
|
37160
|
37161
|
37162
|
37229
|
37230
|
37231
|
37232
|
37233
|
37234
|
37235
|
37236
|
37237
|
37238
|
37239
|
37240
|
37241
|
37242
|
37243
|
37244
|
38247
|
38248
|
38249
|
38250
|
38251
|
38252
|
38253
|
38254
|
38255
|
38256
|
38257
|
38258
|
38259
|
38260
|
38261
|
38262
|
39063
|
39064
|
39065
|
39066
|
39067
|
39069
|
39070
|
39071
|
39072
|
39073
|
39074
|
39075
|
39076
|
39077
|
39078
|
39079
|
39671
|
39672
|
39673
|
39674
|
39675
|
39676
|
39677
|
39678
|
39679
|
39680
|
39681
|
39682
|
39683
|
39684
|
39685
|
39686