+Internal function, not exported, called only by AddReturn.
+
+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.
+
+=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='L' OR accounttype='Rep') ORDER BY date DESC");
+ $sth->execute($itemnumber);
+ my $data = $sth->fetchrow_hashref;
+ $data or return; # bail if there is nothing to do
+
+ # 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 (borrowernumber = ?)
+ AND (itemnumber = ?) AND (accountno = ?) ");
+ $usth->execute($data->{'borrowernumber'},$itemnumber,$acctno); # 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->{'accountno'};
+ # FIXME: move prepares outside while loop!
+ my $usth = $dbh->prepare("UPDATE accountlines SET amountoutstanding= ?
+ WHERE (borrowernumber = ?)
+ AND (accountno=?)");
+ $usth->execute($newamtos,$data->{'borrowernumber'},'$thisacct'); # FIXME: '$thisacct' is a string literal!
+ $usth = $dbh->prepare("INSERT INTO accountoffsets
+ (borrowernumber, accountno, offsetaccount, offsetamount)
+ VALUES
+ (?,?,?,?)");
+ $usth->execute($data->{'borrowernumber'},$accdata->{'accountno'},$nextaccntno,$newamtos);
+ }
+ $msth->finish; # $msth might actually have data left
+ }
+ $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);
+ }
+ ModItem({ paidfor => '' }, undef, $itemnumber);