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

(-)a/C4/Circulation.pm (-209 / +216 lines)
Lines 30-36 use C4::Items; Link Here
30
use C4::Members;
30
use C4::Members;
31
use C4::Dates;
31
use C4::Dates;
32
use C4::Dates qw(format_date);
32
use C4::Dates qw(format_date);
33
use C4::Accounts;
33
use Koha::Accounts;
34
use Koha::Accounts::CreditTypes;
34
use C4::ItemCirculationAlertPreference;
35
use C4::ItemCirculationAlertPreference;
35
use C4::Message;
36
use C4::Message;
36
use C4::Debug;
37
use C4::Debug;
Lines 48-53 use Data::Dumper; Link Here
48
use Koha::DateUtils;
49
use Koha::DateUtils;
49
use Koha::Calendar;
50
use Koha::Calendar;
50
use Koha::Borrower::Debarments;
51
use Koha::Borrower::Debarments;
52
use Koha::Database;
51
use Carp;
53
use Carp;
52
use Date::Calc qw(
54
use Date::Calc qw(
53
  Today
55
  Today
Lines 1292-1298 sub AddIssue { Link Here
1292
        ## If item was lost, it has now been found, reverse any list item charges if neccessary.
1294
        ## If item was lost, it has now been found, reverse any list item charges if neccessary.
1293
        if ( $item->{'itemlost'} ) {
1295
        if ( $item->{'itemlost'} ) {
1294
            if ( C4::Context->preference('RefundLostItemFeeOnReturn' ) ) {
1296
            if ( C4::Context->preference('RefundLostItemFeeOnReturn' ) ) {
1295
                _FixAccountForLostAndReturned( $item->{'itemnumber'}, undef, $item->{'barcode'} );
1297
                _FixAccountForLostAndReturned( $item->{'itemnumber'} );
1296
            }
1298
            }
1297
        }
1299
        }
1298
1300
Lines 1839-1845 sub AddReturn { Link Here
1839
        }
1841
        }
1840
1842
1841
        if ($borrowernumber) {
1843
        if ($borrowernumber) {
1842
            if ( ( C4::Context->preference('CalculateFinesOnReturn') && $issue->{'overdue'} ) || $return_date ) {
1844
            if (
1845
                ( !$item->{itemlost} ) # skip lost items
1846
                && (
1847
                    (
1848
                        C4::Context->preference('CalculateFinesOnReturn')
1849
                        && $issue->{'overdue'}
1850
                    )
1851
                    || $return_date # force fine recalculation in case fine needs reduced
1852
                )
1853
              )
1854
            {
1843
                # we only need to calculate and change the fines if we want to do that on return
1855
                # we only need to calculate and change the fines if we want to do that on return
1844
                # Should be on for hourly loans
1856
                # Should be on for hourly loans
1845
                my $control = C4::Context->preference('CircControl');
1857
                my $control = C4::Context->preference('CircControl');
Lines 1857-1877 sub AddReturn { Link Here
1857
1869
1858
                $type ||= q{};
1870
                $type ||= q{};
1859
1871
1860
                if ( C4::Context->preference('finesMode') eq 'production' ) {
1872
                if ( $amount > 0
1861
                    if ( $amount > 0 ) {
1873
                    && C4::Context->preference('finesMode') eq 'production' )
1862
                        C4::Overdues::UpdateFine( $issue->{itemnumber},
1874
                {
1863
                            $issue->{borrowernumber},
1875
                    C4::Overdues::UpdateFine(
1864
                            $amount, $type, output_pref($datedue) );
1876
                        {
1865
                    }
1877
                            itemnumber     => $issue->{itemnumber},
1866
                    elsif ($return_date) {
1878
                            borrowernumber => $issue->{borrowernumber},
1867
1879
                            amount         => $amount,
1868
                       # Backdated returns may have fines that shouldn't exist,
1880
                            due            => output_pref($datedue),
1869
                       # so in this case, we need to drop those fines to 0
1881
                            issue_id       => $issue->{issue_id}
1870
1882
                        }
1871
                        C4::Overdues::UpdateFine( $issue->{itemnumber},
1883
                    );
1872
                            $issue->{borrowernumber},
1884
                }
1873
                            0, $type, output_pref($datedue) );
1885
                elsif ($return_date) {
1874
                    }
1886
1887
                    # Backdated returns may have fines that shouldn't exist,
1888
                    # so in this case, we need to drop those fines to 0
1889
                    C4::Overdues::UpdateFine(
1890
                        {
1891
                            itemnumber     => $issue->{itemnumber},
1892
                            borrowernumber => $issue->{borrowernumber},
1893
                            amount         => 0,
1894
                            due            => output_pref($datedue),
1895
                            issue_id       => $issue->{issue_id}
1896
                        }
1897
                    );
1875
                }
1898
                }
1876
            }
1899
            }
1877
1900
Lines 1921-1935 sub AddReturn { Link Here
1921
        $messages->{'WasLost'} = 1;
1944
        $messages->{'WasLost'} = 1;
1922
1945
1923
        if ( C4::Context->preference('RefundLostItemFeeOnReturn' ) ) {
1946
        if ( C4::Context->preference('RefundLostItemFeeOnReturn' ) ) {
1924
            _FixAccountForLostAndReturned($item->{'itemnumber'}, $borrowernumber, $barcode);    # can tolerate undef $borrowernumber
1947
            _FixAccountForLostAndReturned( $item->{'itemnumber'} );
1925
            $messages->{'LostItemFeeRefunded'} = 1;
1948
            $messages->{'LostItemFeeRefunded'} = 1;
1926
        }
1949
        }
1927
    }
1950
    }
1928
1951
1929
    # fix up the overdues in accounts...
1952
    # fix up the overdues in accounts...
1930
    if ($borrowernumber) {
1953
    if ($borrowernumber) {
1931
        my $fix = _FixOverduesOnReturn($borrowernumber, $item->{itemnumber}, $exemptfine, $dropbox);
1954
        _FinalizeFine(
1932
        defined($fix) or warn "_FixOverduesOnReturn($borrowernumber, $item->{itemnumber}...) failed!";  # zero is OK, check defined
1955
            {
1956
                exempt_fine => $exemptfine,
1957
                dropbox     => $dropbox,
1958
                issue       => Koha::Database->new()->schema->resultset('OldIssue')->find( $issue->{issue_id} ),
1959
            }
1960
        );
1933
        
1961
        
1934
        if ( $issue->{overdue} && $issue->{date_due} ) {
1962
        if ( $issue->{overdue} && $issue->{date_due} ) {
1935
        # fix fine days
1963
        # fix fine days
Lines 2038-2047 of the return. It is ignored when a dropbox_branch is passed in. Link Here
2038
C<$privacy> contains the privacy parameter. If the patron has set privacy to 2,
2066
C<$privacy> contains the privacy parameter. If the patron has set privacy to 2,
2039
the old_issue is immediately anonymised
2067
the old_issue is immediately anonymised
2040
2068
2041
Ideally, this function would be internal to C<C4::Circulation>,
2042
not exported, but it is currently needed by one 
2043
routine in C<C4::Accounts>.
2044
2045
=cut
2069
=cut
2046
2070
2047
sub MarkIssueReturned {
2071
sub MarkIssueReturned {
Lines 2163-2317 sub _debar_user_on_return { Link Here
2163
    return;
2187
    return;
2164
}
2188
}
2165
2189
2166
=head2 _FixOverduesOnReturn
2190
=head2 _FinalizeFine
2167
2168
   &_FixOverduesOnReturn($brn,$itm, $exemptfine, $dropboxmode);
2169
2170
C<$brn> borrowernumber
2171
2191
2172
C<$itm> itemnumber
2192
   _FinalizeFine({
2193
        exempt_fine => $exempt_fine,
2194
        dropbox     => $dropbox,
2195
        issue       => $issue,
2196
   });
2173
2197
2174
C<$exemptfine> BOOL -- remove overdue charge associated with this issue. 
2198
C<$exemptfine> BOOL -- remove overdue charge associated with this issue. 
2175
C<$dropboxmode> BOOL -- remove lastincrement on overdue charge associated with this issue.
2199
C<$dropboxmode> BOOL -- remove lastincrement on overdue charge associated with this issue.
2200
C<$issue> -- DBIx::Class::Row for the issue
2176
2201
2177
Internal function, called only by AddReturn
2202
This subrouting closes out the accuruing of a fine, and reduces if it exemptfine or
2203
dropbox flags are passed in.
2178
2204
2179
=cut
2205
=cut
2180
2206
2181
sub _FixOverduesOnReturn {
2207
sub _FinalizeFine {
2182
    my ($borrowernumber, $item);
2208
    my ( $params ) = @_;
2183
    unless ($borrowernumber = shift) {
2209
2184
        warn "_FixOverduesOnReturn() not supplied valid borrowernumber";
2210
    my $exemptfine = $params->{exempt_fine};
2185
        return;
2211
    my $dropbox    = $params->{dropbox};
2186
    }
2212
    my $issue      = $params->{issue};
2187
    unless ($item = shift) {
2213
2188
        warn "_FixOverduesOnReturn() not supplied valid itemnumber";
2189
        return;
2190
    }
2191
    my ($exemptfine, $dropbox) = @_;
2192
    my $dbh = C4::Context->dbh;
2214
    my $dbh = C4::Context->dbh;
2193
2215
2194
    # check for overdue fine
2216
    my $schema = Koha::Database->new()->schema;
2195
    my $sth = $dbh->prepare(
2217
    my $fine = $schema->resultset('AccountDebit')->single(
2196
"SELECT * FROM accountlines WHERE (borrowernumber = ?) AND (itemnumber = ?) AND (accounttype='FU' OR accounttype='O')"
2218
        {
2219
            issue_id => $issue->issue_id(),
2220
            type     => Koha::Accounts::DebitTypes::Fine(),
2221
            accruing => 1,
2222
        }
2197
    );
2223
    );
2198
    $sth->execute( $borrowernumber, $item );
2199
2224
2200
    # alter fine to show that the book has been returned
2225
    return unless ( $fine );
2201
    my $data = $sth->fetchrow_hashref;
2226
2202
    return 0 unless $data;    # no warning, there's just nothing to fix
2227
    $fine->accruing(0);
2203
2228
2204
    my $uquery;
2205
    my @bind = ($data->{'accountlines_id'});
2206
    if ($exemptfine) {
2229
    if ($exemptfine) {
2207
        $uquery = "update accountlines set accounttype='FFOR', amountoutstanding=0";
2230
        AddCredit(
2208
        if (C4::Context->preference("FinesLog")) {
2231
            {
2209
            &logaction("FINES", 'MODIFY',$borrowernumber,"Overdue forgiven: item $item");
2232
                borrower => $fine->borrowernumber(),
2210
        }
2233
                amount   => $fine->amount_original(),
2211
    } elsif ($dropbox && $data->{lastincrement}) {
2234
                debit_id => $fine->debit_id(),
2212
        my $outstanding = $data->{amountoutstanding} - $data->{lastincrement} ;
2235
                type     => Koha::Accounts::CreditTypes::Forgiven(),
2213
        my $amt = $data->{amount} - $data->{lastincrement} ;
2236
            }
2237
        );
2214
        if (C4::Context->preference("FinesLog")) {
2238
        if (C4::Context->preference("FinesLog")) {
2215
            &logaction("FINES", 'MODIFY',$borrowernumber,"Dropbox adjustment $amt, item $item");
2239
            &logaction(
2216
        }
2240
                "FINES", 'MODIFY',
2217
         $uquery = "update accountlines set accounttype='F' ";
2241
                $issue->{borrowernumber},
2218
         if($outstanding  >= 0 && $amt >=0) {
2242
                "Overdue forgiven: item " . $issue->{itemnumber}
2219
            $uquery .= ", amount = ? , amountoutstanding=? ";
2243
            );
2220
            unshift @bind, ($amt, $outstanding) ;
2221
        }
2244
        }
2222
    } else {
2245
    } elsif ($dropbox && $fine->amount_last_increment() != $fine->amount_original() ) {
2223
        $uquery = "update accountlines set accounttype='F' ";
2246
        if ( C4::Context->preference("FinesLog") ) {
2247
            &logaction( "FINES", 'MODIFY', $issue->{borrowernumber},
2248
                    "Dropbox adjustment "
2249
                  . $fine->amount_last_increment()
2250
                  . ", item " . $issue->{itemnumber} );
2251
        }
2252
        $fine->amount_original(
2253
            $fine->amount_original() - $fine->amount_last_increment() );
2254
        $fine->amount_outstanding(
2255
            $fine->amount_outstanding - $fine->amount_last_increment() );
2256
        $schema->resultset('AccountOffset')->create(
2257
            {
2258
                debit_id => $fine->debit_id(),
2259
                type     => Koha::Accounts::OffsetTypes::Dropbox(),
2260
                amount   => $fine->amount_last_increment() * -1,
2261
            }
2262
        );
2224
    }
2263
    }
2225
    $uquery .= " where (accountlines_id = ?)";
2264
2226
    my $usth = $dbh->prepare($uquery);
2265
    return $fine->update();
2227
    return $usth->execute(@bind);
2228
}
2266
}
2229
2267
2230
=head2 _FixAccountForLostAndReturned
2268
=head2 _FixAccountForLostAndReturned
2231
2269
2232
  &_FixAccountForLostAndReturned($itemnumber, [$borrowernumber, $barcode]);
2270
  &_FixAccountForLostAndReturned($itemnumber);
2233
2234
Calculates the charge for a book lost and returned.
2235
2236
Internal function, not exported, called only by AddReturn.
2237
2271
2238
FIXME: This function reflects how inscrutable fines logic is.  Fix both.
2272
  Refunds a lost item fee in necessary
2239
FIXME: Give a positive return value on success.  It might be the $borrowernumber who received credit, or the amount forgiven.
2240
2273
2241
=cut
2274
=cut
2242
2275
2243
sub _FixAccountForLostAndReturned {
2276
sub _FixAccountForLostAndReturned {
2244
    my $itemnumber     = shift or return;
2277
    my ( $itemnumber ) = @_;
2245
    my $borrowernumber = @_ ? shift : undef;
2278
2246
    my $item_id        = @_ ? shift : $itemnumber;  # Send the barcode if you want that logged in the description
2279
    my $schema = Koha::Database->new()->schema;
2247
    my $dbh = C4::Context->dbh;
2280
2248
    # check for charge made for lost book
2281
    # Find the last issue for this item
2249
    my $sth = $dbh->prepare("SELECT * FROM accountlines WHERE itemnumber = ? AND accounttype IN ('L', 'Rep', 'W') ORDER BY date DESC, accountno DESC");
2282
    my $issue =
2250
    $sth->execute($itemnumber);
2283
      $schema->resultset('Issue')->single( { itemnumber => $itemnumber } );
2251
    my $data = $sth->fetchrow_hashref;
2284
    $issue ||=
2252
    $data or return;    # bail if there is nothing to do
2285
      $schema->resultset('OldIssue')->single( { itemnumber => $itemnumber } );
2253
    $data->{accounttype} eq 'W' and return;    # Written off
2286
2254
2287
    return unless $issue;
2255
    # writeoff this amount
2288
2256
    my $offset;
2289
    # Find a lost fee for this issue
2257
    my $amount = $data->{'amount'};
2290
    my $debit = $schema->resultset('AccountDebit')->single(
2258
    my $acctno = $data->{'accountno'};
2291
        {
2259
    my $amountleft;                                             # Starts off undef/zero.
2292
            issue_id => $issue->issue_id(),
2260
    if ($data->{'amountoutstanding'} == $amount) {
2293
            type     => Koha::Accounts::DebitTypes::Lost()
2261
        $offset     = $data->{'amount'};
2294
        }
2262
        $amountleft = 0;                                        # Hey, it's zero here, too.
2295
    );
2263
    } else {
2296
2264
        $offset     = $amount - $data->{'amountoutstanding'};   # Um, isn't this the same as ZERO?  We just tested those two things are ==
2297
    return unless $debit;
2265
        $amountleft = $data->{'amountoutstanding'} - $amount;   # Um, isn't this the same as ZERO?  We just tested those two things are ==
2298
2266
    }
2299
    # Check for an existing found credit for this debit, if there is one, the fee has already been refunded and we do nothing
2267
    my $usth = $dbh->prepare("UPDATE accountlines SET accounttype = 'LR',amountoutstanding='0'
2300
    my @credits = $debit->account_offsets->search_related('credit', { 'credit.type' => Koha::Accounts::CreditTypes::Found() });
2268
        WHERE (accountlines_id = ?)");
2301
2269
    $usth->execute($data->{'accountlines_id'});      # We might be adjusting an account for some OTHER borrowernumber now.  Not the one we passed in.
2302
    return if @credits;
2270
    #check if any credit is left if so writeoff other accounts
2303
2271
    my $nextaccntno = getnextacctno($data->{'borrowernumber'});
2304
    # Ok, so we know we have an unrefunded lost item fee, let's refund it
2272
    $amountleft *= -1 if ($amountleft < 0);
2305
    CreditLostItem(
2273
    if ($amountleft > 0) {
2306
        {
2274
        my $msth = $dbh->prepare("SELECT * FROM accountlines WHERE (borrowernumber = ?)
2307
            borrower => $issue->borrower(),
2275
                            AND (amountoutstanding >0) ORDER BY date");     # might want to order by amountoustanding ASC (pay smallest first)
2308
            debit    => $debit
2276
        $msth->execute($data->{'borrowernumber'});
2309
        }
2277
        # offset transactions
2310
    );
2278
        my $newamtos;
2311
2279
        my $accdata;
2280
        while (($accdata=$msth->fetchrow_hashref) and ($amountleft>0)){
2281
            if ($accdata->{'amountoutstanding'} < $amountleft) {
2282
                $newamtos = 0;
2283
                $amountleft -= $accdata->{'amountoutstanding'};
2284
            }  else {
2285
                $newamtos = $accdata->{'amountoutstanding'} - $amountleft;
2286
                $amountleft = 0;
2287
            }
2288
            my $thisacct = $accdata->{'accountlines_id'};
2289
            # FIXME: move prepares outside while loop!
2290
            my $usth = $dbh->prepare("UPDATE accountlines SET amountoutstanding= ?
2291
                    WHERE (accountlines_id = ?)");
2292
            $usth->execute($newamtos,$thisacct);
2293
            $usth = $dbh->prepare("INSERT INTO accountoffsets
2294
                (borrowernumber, accountno, offsetaccount,  offsetamount)
2295
                VALUES
2296
                (?,?,?,?)");
2297
            $usth->execute($data->{'borrowernumber'},$accdata->{'accountno'},$nextaccntno,$newamtos);
2298
        }
2299
    }
2300
    $amountleft *= -1 if ($amountleft > 0);
2301
    my $desc = "Item Returned " . $item_id;
2302
    $usth = $dbh->prepare("INSERT INTO accountlines
2303
        (borrowernumber,accountno,date,amount,description,accounttype,amountoutstanding)
2304
        VALUES (?,?,now(),?,?,'CR',?)");
2305
    $usth->execute($data->{'borrowernumber'},$nextaccntno,0-$amount,$desc,$amountleft);
2306
    if ($borrowernumber) {
2307
        # FIXME: same as query above.  use 1 sth for both
2308
        $usth = $dbh->prepare("INSERT INTO accountoffsets
2309
            (borrowernumber, accountno, offsetaccount,  offsetamount)
2310
            VALUES (?,?,?,?)");
2311
        $usth->execute($borrowernumber, $data->{'accountno'}, $nextaccntno, $offset);
2312
    }
2313
    ModItem({ paidfor => '' }, undef, $itemnumber);
2312
    ModItem({ paidfor => '' }, undef, $itemnumber);
2314
    return;
2315
}
2313
}
2316
2314
2317
=head2 _GetCircControlBranch
2315
=head2 _GetCircControlBranch
Lines 2704-2717 sub AddRenewal { Link Here
2704
    my $dbh = C4::Context->dbh;
2702
    my $dbh = C4::Context->dbh;
2705
2703
2706
    # Find the issues record for this book
2704
    # Find the issues record for this book
2707
    my $sth =
2705
    my $issue = Koha::Database->new()->schema->resultset('Issue')->single({ itemnumber => $itemnumber });
2708
      $dbh->prepare("SELECT * FROM issues WHERE itemnumber = ?");
2709
    $sth->execute( $itemnumber );
2710
    my $issuedata = $sth->fetchrow_hashref;
2711
2706
2712
    return unless ( $issuedata );
2707
    return unless ( $issue );
2713
2708
2714
    $borrowernumber ||= $issuedata->{borrowernumber};
2709
    $borrowernumber ||= $issue->get_column('borrowernumber');
2715
2710
2716
    if ( defined $datedue && ref $datedue ne 'DateTime' ) {
2711
    if ( defined $datedue && ref $datedue ne 'DateTime' ) {
2717
        carp 'Invalid date passed to AddRenewal.';
2712
        carp 'Invalid date passed to AddRenewal.';
Lines 2727-2767 sub AddRenewal { Link Here
2727
        my $itemtype = (C4::Context->preference('item-level_itypes')) ? $biblio->{'itype'} : $biblio->{'itemtype'};
2722
        my $itemtype = (C4::Context->preference('item-level_itypes')) ? $biblio->{'itype'} : $biblio->{'itemtype'};
2728
2723
2729
        $datedue = (C4::Context->preference('RenewalPeriodBase') eq 'date_due') ?
2724
        $datedue = (C4::Context->preference('RenewalPeriodBase') eq 'date_due') ?
2730
                                        dt_from_string( $issuedata->{date_due} ) :
2725
                                        dt_from_string( $issue->get_column('date_due') ) :
2731
                                        DateTime->now( time_zone => C4::Context->tz());
2726
                                        DateTime->now( time_zone => C4::Context->tz());
2732
        $datedue =  CalcDateDue($datedue, $itemtype, $issuedata->{'branchcode'}, $borrower, 'is a renewal');
2727
        $datedue =  CalcDateDue($datedue, $itemtype, $issue->get_column('branchcode'), $borrower, 'is a renewal');
2733
    }
2728
    }
2734
2729
2735
    # Update the issues record to have the new due date, and a new count
2730
    # Update the issues record to have the new due date, and a new count
2736
    # of how many times it has been renewed.
2731
    # of how many times it has been renewed.
2737
    my $renews = $issuedata->{'renewals'} + 1;
2732
    $issue->update(
2738
    $sth = $dbh->prepare("UPDATE issues SET date_due = ?, renewals = ?, lastreneweddate = ?
2733
        {
2739
                            WHERE borrowernumber=? 
2734
            date_due        => $datedue->strftime('%Y-%m-%d %H:%M'),
2740
                            AND itemnumber=?"
2735
            renewals        => $issue->renewals() + 1,
2736
            lastreneweddate => $lastreneweddate,
2737
        }
2741
    );
2738
    );
2742
2739
2743
    $sth->execute( $datedue->strftime('%Y-%m-%d %H:%M'), $renews, $lastreneweddate, $borrowernumber, $itemnumber );
2744
2740
2745
    # Update the renewal count on the item, and tell zebra to reindex
2741
    # Update the renewal count on the item, and tell zebra to reindex
2746
    $renews = $biblio->{'renewals'} + 1;
2742
    my $renews = $biblio->{'renewals'} + 1;
2747
    ModItem({ renewals => $renews, onloan => $datedue->strftime('%Y-%m-%d %H:%M')}, $biblio->{'biblionumber'}, $itemnumber);
2743
    ModItem({ renewals => $renews, onloan => $datedue->strftime('%Y-%m-%d %H:%M')}, $biblio->{'biblionumber'}, $itemnumber);
2748
2744
2749
    # Charge a new rental fee, if applicable?
2745
    # Charge a new rental fee, if applicable?
2750
    my ( $charge, $type ) = GetIssuingCharges( $itemnumber, $borrowernumber );
2746
    my ( $charge, $type ) = GetIssuingCharges( $itemnumber, $borrowernumber );
2751
    if ( $charge > 0 ) {
2747
    if ( $charge > 0 ) {
2752
        my $accountno = getnextacctno( $borrowernumber );
2753
        my $item = GetBiblioFromItemNumber($itemnumber);
2748
        my $item = GetBiblioFromItemNumber($itemnumber);
2754
        my $manager_id = 0;
2749
2755
        $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv; 
2750
        my $borrower =
2756
        $sth = $dbh->prepare(
2751
          Koha::Database->new()->schema->resultset('Borrower')
2757
                "INSERT INTO accountlines
2752
          ->find($borrowernumber);
2758
                    (date, borrowernumber, accountno, amount, manager_id,
2753
2759
                    description,accounttype, amountoutstanding, itemnumber)
2754
        AddDebit(
2760
                    VALUES (now(),?,?,?,?,?,?,?,?)"
2755
            {
2756
                borrower   => $borrower,
2757
                itemnumber => $itemnumber,
2758
                amount     => $charge,
2759
                type       => Koha::Accounts::DebitTypes::Rental(),
2760
                description =>
2761
                  "Renewal of Rental Item $item->{'title'} $item->{'barcode'}"
2762
            }
2761
        );
2763
        );
2762
        $sth->execute( $borrowernumber, $accountno, $charge, $manager_id,
2763
            "Renewal of Rental Item $item->{'title'} $item->{'barcode'}",
2764
            'Rent', $charge, $itemnumber );
2765
    }
2764
    }
2766
2765
2767
    # Send a renewal slip according to checkout alert preferencei
2766
    # Send a renewal slip according to checkout alert preferencei
Lines 2803-2808 sub AddRenewal { Link Here
2803
                borrowernumber => $borrowernumber,
2802
                borrowernumber => $borrowernumber,
2804
                ccode => $item->{'ccode'}}
2803
                ccode => $item->{'ccode'}}
2805
                );
2804
                );
2805
2806
    _FinalizeFine( { issue => $issue } );
2807
2806
	return $datedue;
2808
	return $datedue;
2807
}
2809
}
2808
2810
Lines 2987-3011 sub _get_discount_from_rule { Link Here
2987
2989
2988
=head2 AddIssuingCharge
2990
=head2 AddIssuingCharge
2989
2991
2990
  &AddIssuingCharge( $itemno, $borrowernumber, $charge )
2992
  &AddIssuingCharge( $itemnumber, $borrowernumber, $amount )
2991
2993
2992
=cut
2994
=cut
2993
2995
2994
sub AddIssuingCharge {
2996
sub AddIssuingCharge {
2995
    my ( $itemnumber, $borrowernumber, $charge ) = @_;
2997
    my ( $itemnumber, $borrowernumber, $amount ) = @_;
2996
    my $dbh = C4::Context->dbh;
2998
2997
    my $nextaccntno = getnextacctno( $borrowernumber );
2999
    return AddDebit(
2998
    my $manager_id = 0;
3000
        {
2999
    $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
3001
            borrower       => Koha::Database->new()->schema->resultset('Borrower')->find($borrowernumber),
3000
    my $query ="
3002
            itemnumber     => $itemnumber,
3001
        INSERT INTO accountlines
3003
            amount         => $amount,
3002
            (borrowernumber, itemnumber, accountno,
3004
            type           => Koha::Accounts::DebitTypes::Rental(),
3003
            date, amount, description, accounttype,
3005
        }
3004
            amountoutstanding, manager_id)
3006
    );
3005
        VALUES (?, ?, ?,now(), ?, 'Rental', 'Rent',?,?)
3006
    ";
3007
    my $sth = $dbh->prepare($query);
3008
    $sth->execute( $borrowernumber, $itemnumber, $nextaccntno, $charge, $charge, $manager_id );
3009
}
3007
}
3010
3008
3011
=head2 GetTransfers
3009
=head2 GetTransfers
Lines 3524-3553 sub ReturnLostItem{ Link Here
3524
sub LostItem{
3522
sub LostItem{
3525
    my ($itemnumber, $mark_returned) = @_;
3523
    my ($itemnumber, $mark_returned) = @_;
3526
3524
3527
    my $dbh = C4::Context->dbh();
3525
    my $schema = Koha::Database->new()->schema;
3528
    my $sth=$dbh->prepare("SELECT issues.*,items.*,biblio.title 
3529
                           FROM issues 
3530
                           JOIN items USING (itemnumber) 
3531
                           JOIN biblio USING (biblionumber)
3532
                           WHERE issues.itemnumber=?");
3533
    $sth->execute($itemnumber);
3534
    my $issues=$sth->fetchrow_hashref();
3535
3526
3536
    # If a borrower lost the item, add a replacement cost to the their record
3527
    my $issue =
3537
    if ( my $borrowernumber = $issues->{borrowernumber} ){
3528
      $schema->resultset('Issue')->single( { itemnumber => $itemnumber } );
3538
        my $borrower = C4::Members::GetMemberDetails( $borrowernumber );
3539
3529
3530
    my ( $borrower, $item );
3531
3532
    if ( $issue ) {
3533
        $borrower = $issue->borrower();
3534
        $item     = $issue->item();
3535
    }
3536
3537
    # If a borrower lost the item, add a replacement cost to the their record
3538
    if ( $borrower ){
3540
        if (C4::Context->preference('WhenLostForgiveFine')){
3539
        if (C4::Context->preference('WhenLostForgiveFine')){
3541
            my $fix = _FixOverduesOnReturn($borrowernumber, $itemnumber, 1, 0); # 1, 0 = exemptfine, no-dropbox
3540
            _FinalizeFine(
3542
            defined($fix) or warn "_FixOverduesOnReturn($borrowernumber, $itemnumber...) failed!";  # zero is OK, check defined
3541
                {
3542
                    exempt_fine => 1,
3543
                    dropbox     => 0,
3544
                    issue       => $issue,
3545
                }
3546
            );
3543
        }
3547
        }
3544
        if (C4::Context->preference('WhenLostChargeReplacementFee')){
3548
        if ( C4::Context->preference('WhenLostChargeReplacementFee') ) {
3545
            C4::Accounts::chargelostitem($borrowernumber, $itemnumber, $issues->{'replacementprice'}, "Lost Item $issues->{'title'} $issues->{'barcode'}");
3549
            DebitLostItem( { borrower => $borrower, issue => $issue } );
3546
            #FIXME : Should probably have a way to distinguish this from an item that really was returned.
3547
            #warn " $issues->{'borrowernumber'}  /  $itemnumber ";
3548
        }
3550
        }
3549
3551
3550
        MarkIssueReturned($borrowernumber,$itemnumber,undef,undef,$borrower->{'privacy'}) if $mark_returned;
3552
        MarkIssueReturned( $borrower->borrowernumber(), $item->itemnumber(), undef, undef, $borrower->privacy() ) if $mark_returned;
3551
    }
3553
    }
3552
}
3554
}
3553
3555
Lines 3665-3674 sub ProcessOfflineIssue { Link Here
3665
sub ProcessOfflinePayment {
3667
sub ProcessOfflinePayment {
3666
    my $operation = shift;
3668
    my $operation = shift;
3667
3669
3668
    my $borrower = C4::Members::GetMemberDetails( undef, $operation->{cardnumber} ); # Get borrower from operation cardnumber
3670
    AddCredit(
3669
    my $amount = $operation->{amount};
3671
        {
3670
3672
            borrower => Koha::Database->new()->schema->resultset('Borrower')
3671
    recordpayment( $borrower->{borrowernumber}, $amount );
3673
              ->single( { cardnumber => $operation->{cardnumber} } ),
3674
            amount => $operation->{amount},
3675
            notes  => 'via offline circulation',
3676
            type   => Koha::Accounts::CreditTypes::Payment,
3677
        }
3678
    );
3672
3679
3673
    return "Success."
3680
    return "Success."
3674
}
3681
}
(-)a/C4/ILSDI/Services.pm (-5 / +4 lines)
Lines 24-30 use C4::Members; Link Here
24
use C4::Items;
24
use C4::Items;
25
use C4::Circulation;
25
use C4::Circulation;
26
use C4::Branch;
26
use C4::Branch;
27
use C4::Accounts;
28
use C4::Biblio;
27
use C4::Biblio;
29
use C4::Reserves qw(AddReserve GetReservesFromBiblionumber GetReservesFromBorrowernumber CanBookBeReserved CanItemBeReserved);
28
use C4::Reserves qw(AddReserve GetReservesFromBiblionumber GetReservesFromBorrowernumber CanBookBeReserved CanItemBeReserved);
30
use C4::Context;
29
use C4::Context;
Lines 34-39 use HTML::Entities; Link Here
34
use CGI;
33
use CGI;
35
use DateTime;
34
use DateTime;
36
use C4::Auth;
35
use C4::Auth;
36
use Koha::Database;
37
37
38
=head1 NAME
38
=head1 NAME
39
39
Lines 387-396 sub GetPatronInfo { Link Here
387
387
388
    # Fines management
388
    # Fines management
389
    if ( $cgi->param('show_fines') eq "1" ) {
389
    if ( $cgi->param('show_fines') eq "1" ) {
390
        my @charges;
390
        my @charges =
391
        for ( my $i = 1 ; my @charge = getcharges( $borrowernumber, undef, $i ) ; $i++ ) {
391
          Koha::Database->new()->schema()->resultset('AccountDebit')
392
            push( @charges, @charge );
392
          ->search( { borrowernumber => $borrowernumber } );
393
        }
394
        $borrower->{'fines'}->{'fine'} = \@charges;
393
        $borrower->{'fines'}->{'fine'} = \@charges;
395
    }
394
    }
396
395
(-)a/C4/Members.pm (-134 / +54 lines)
Lines 29-35 use Date::Calc qw/Today Add_Delta_YM check_date Date_to_Days/; Link Here
29
use C4::Log; # logaction
29
use C4::Log; # logaction
30
use C4::Overdues;
30
use C4::Overdues;
31
use C4::Reserves;
31
use C4::Reserves;
32
use C4::Accounts;
33
use C4::Biblio;
32
use C4::Biblio;
34
use C4::Letters;
33
use C4::Letters;
35
use C4::SQLHelper qw(InsertInTable UpdateInTable SearchInTable);
34
use C4::SQLHelper qw(InsertInTable UpdateInTable SearchInTable);
Lines 42-47 use Koha::Borrower::Debarments qw(IsDebarred); Link Here
42
use Text::Unaccent qw( unac_string );
41
use Text::Unaccent qw( unac_string );
43
use Koha::AuthUtils qw(hash_password);
42
use Koha::AuthUtils qw(hash_password);
44
use Koha::Database;
43
use Koha::Database;
44
use Koha::Accounts::DebitTypes;
45
45
46
our ($VERSION,@ISA,@EXPORT,@EXPORT_OK,$debug);
46
our ($VERSION,@ISA,@EXPORT,@EXPORT_OK,$debug);
47
47
Lines 81-88 BEGIN { Link Here
81
        &GetHideLostItemsPreference
81
        &GetHideLostItemsPreference
82
82
83
        &IsMemberBlocked
83
        &IsMemberBlocked
84
        &GetMemberAccountRecords
85
        &GetBorNotifyAcctRecord
86
84
87
        &GetborCatFromCatType
85
        &GetborCatFromCatType
88
        &GetBorrowercategory
86
        &GetBorrowercategory
Lines 356-364 sub GetMemberDetails { Link Here
356
    }
354
    }
357
    my $borrower = $sth->fetchrow_hashref;
355
    my $borrower = $sth->fetchrow_hashref;
358
    return unless $borrower;
356
    return unless $borrower;
359
    my ($amount) = GetMemberAccountRecords( $borrowernumber);
357
    $borrower->{amountoutstanding} = $borrower->{account_balance};
360
    $borrower->{'amountoutstanding'} = $amount;
358
    # FIXME - find all references to $borrower->{amountoutstanding}, replace with $borrower->{account_balance}
361
    # FIXME - patronflags calls GetMemberAccountRecords... just have patronflags return $amount
362
    my $flags = patronflags( $borrower);
359
    my $flags = patronflags( $borrower);
363
    my $accessflagshash;
360
    my $accessflagshash;
364
361
Lines 462-484 The "message" field that comes from the DB is OK. Link Here
462
# FIXME rename this function.
459
# FIXME rename this function.
463
sub patronflags {
460
sub patronflags {
464
    my %flags;
461
    my %flags;
465
    my ( $patroninformation) = @_;
462
    my ($patroninformation) = @_;
466
    my $dbh=C4::Context->dbh;
463
    my $dbh = C4::Context->dbh;
467
    my ($balance, $owing) = GetMemberAccountBalance( $patroninformation->{'borrowernumber'});
464
    if ( $patroninformation->{account_balance} > 0 ) {
468
    if ( $owing > 0 ) {
469
        my %flaginfo;
465
        my %flaginfo;
470
        my $noissuescharge = C4::Context->preference("noissuescharge") || 5;
466
        my $noissuescharge = C4::Context->preference("noissuescharge") || 5;
471
        $flaginfo{'message'} = sprintf 'Patron owes %.02f', $owing;
467
        $flaginfo{'amount'}  = $patroninformation->{account_balance};
472
        $flaginfo{'amount'}  = sprintf "%.02f", $owing;
468
        if (  $patroninformation->{account_balance} > $noissuescharge && !C4::Context->preference("AllowFineOverride") ) {
473
        if ( $owing > $noissuescharge && !C4::Context->preference("AllowFineOverride") ) {
474
            $flaginfo{'noissues'} = 1;
469
            $flaginfo{'noissues'} = 1;
475
        }
470
        }
476
        $flags{'CHARGES'} = \%flaginfo;
471
        $flags{'CHARGES'} = \%flaginfo;
477
    }
472
    }
478
    elsif ( $balance < 0 ) {
473
    elsif ( $patroninformation->{account_balance} < 0 ) {
479
        my %flaginfo;
474
        my %flaginfo;
480
        $flaginfo{'message'} = sprintf 'Patron has credit of %.02f', -$balance;
475
        $flaginfo{'amount'}  = $patroninformation->{account_balance};
481
        $flaginfo{'amount'}  = sprintf "%.02f", $balance;
482
        $flags{'CREDITS'} = \%flaginfo;
476
        $flags{'CREDITS'} = \%flaginfo;
483
    }
477
    }
484
    if (   $patroninformation->{'gonenoaddress'}
478
    if (   $patroninformation->{'gonenoaddress'}
Lines 722-728 sub GetMemberIssuesAndFines { Link Here
722
    $sth->execute($borrowernumber);
716
    $sth->execute($borrowernumber);
723
    my $overdue_count = $sth->fetchrow_arrayref->[0];
717
    my $overdue_count = $sth->fetchrow_arrayref->[0];
724
718
725
    $sth = $dbh->prepare("SELECT SUM(amountoutstanding) FROM accountlines WHERE borrowernumber = ?");
719
    $sth = $dbh->prepare("SELECT account_balance FROM borrowers WHERE borrowernumber = ?");
726
    $sth->execute($borrowernumber);
720
    $sth->execute($borrowernumber);
727
    my $total_fines = $sth->fetchrow_arrayref->[0];
721
    my $total_fines = $sth->fetchrow_arrayref->[0];
728
722
Lines 1211-1267 sub GetAllIssues { Link Here
1211
}
1205
}
1212
1206
1213
1207
1214
=head2 GetMemberAccountRecords
1215
1216
  ($total, $acctlines, $count) = &GetMemberAccountRecords($borrowernumber);
1217
1218
Looks up accounting data for the patron with the given borrowernumber.
1219
1220
C<&GetMemberAccountRecords> returns a three-element array. C<$acctlines> is a
1221
reference-to-array, where each element is a reference-to-hash; the
1222
keys are the fields of the C<accountlines> table in the Koha database.
1223
C<$count> is the number of elements in C<$acctlines>. C<$total> is the
1224
total amount outstanding for all of the account lines.
1225
1226
=cut
1227
1228
sub GetMemberAccountRecords {
1229
    my ($borrowernumber) = @_;
1230
    my $dbh = C4::Context->dbh;
1231
    my @acctlines;
1232
    my $numlines = 0;
1233
    my $strsth      = qq(
1234
                        SELECT * 
1235
                        FROM accountlines 
1236
                        WHERE borrowernumber=?);
1237
    $strsth.=" ORDER BY date desc,timestamp DESC";
1238
    my $sth= $dbh->prepare( $strsth );
1239
    $sth->execute( $borrowernumber );
1240
1241
    my $total = 0;
1242
    while ( my $data = $sth->fetchrow_hashref ) {
1243
        if ( $data->{itemnumber} ) {
1244
            my $biblio = GetBiblioFromItemNumber( $data->{itemnumber} );
1245
            $data->{biblionumber} = $biblio->{biblionumber};
1246
            $data->{title}        = $biblio->{title};
1247
        }
1248
        $acctlines[$numlines] = $data;
1249
        $numlines++;
1250
        $total += int(1000 * $data->{'amountoutstanding'}); # convert float to integer to avoid round-off errors
1251
    }
1252
    $total /= 1000;
1253
    return ( $total, \@acctlines,$numlines);
1254
}
1255
1256
=head2 GetMemberAccountBalance
1208
=head2 GetMemberAccountBalance
1257
1209
1258
  ($total_balance, $non_issue_balance, $other_charges) = &GetMemberAccountBalance($borrowernumber);
1210
  ($total_balance, $non_issue_balance, $other_charges) = &GetMemberAccountBalance($borrowernumber);
1259
1211
1260
Calculates amount immediately owing by the patron - non-issue charges.
1212
Calculates amount immediately owing by the patron - non-issue charges.
1261
Based on GetMemberAccountRecords.
1262
Charges exempt from non-issue are:
1213
Charges exempt from non-issue are:
1263
* Res (reserves)
1214
* HOLD fees (reserves)
1264
* Rent (rental) if RentalsInNoissuesCharge syspref is set to false
1215
* RENTAL if RentalsInNoissuesCharge syspref is set to false
1265
* Manual invoices if ManInvInNoissuesCharge syspref is set to false
1216
* Manual invoices if ManInvInNoissuesCharge syspref is set to false
1266
1217
1267
=cut
1218
=cut
Lines 1269-1339 Charges exempt from non-issue are: Link Here
1269
sub GetMemberAccountBalance {
1220
sub GetMemberAccountBalance {
1270
    my ($borrowernumber) = @_;
1221
    my ($borrowernumber) = @_;
1271
1222
1272
    my $ACCOUNT_TYPE_LENGTH = 5; # this is plain ridiculous...
1223
    my $borrower =
1224
      Koha::Database->new()->schema->resultset('Borrower')
1225
      ->find($borrowernumber);
1273
1226
1274
    my @not_fines;
1227
    my @not_fines;
1275
    push @not_fines, 'Res' unless C4::Context->preference('HoldsInNoissuesCharge');
1276
    push @not_fines, 'Rent' unless C4::Context->preference('RentalsInNoissuesCharge');
1277
    unless ( C4::Context->preference('ManInvInNoissuesCharge') ) {
1278
        my $dbh = C4::Context->dbh;
1279
        my $man_inv_types = $dbh->selectcol_arrayref(qq{SELECT authorised_value FROM authorised_values WHERE category = 'MANUAL_INV'});
1280
        push @not_fines, map substr($_, 0, $ACCOUNT_TYPE_LENGTH), @$man_inv_types;
1281
    }
1282
    my %not_fine = map {$_ => 1} @not_fines;
1283
1284
    my ($total, $acctlines) = GetMemberAccountRecords($borrowernumber);
1285
    my $other_charges = 0;
1286
    foreach (@$acctlines) {
1287
        $other_charges += $_->{amountoutstanding} if $not_fine{ substr($_->{accounttype}, 0, $ACCOUNT_TYPE_LENGTH) };
1288
    }
1289
1290
    return ( $total, $total - $other_charges, $other_charges);
1291
}
1292
1228
1293
=head2 GetBorNotifyAcctRecord
1229
    push( @not_fines, Koha::Accounts::DebitTypes::Hold() );
1294
1230
1295
  ($total, $acctlines, $count) = &GetBorNotifyAcctRecord($params,$notifyid);
1231
    push( @not_fines, Koha::Accounts::DebitTypes::Rental() )
1232
      unless C4::Context->preference('RentalsInNoissuesCharge');
1296
1233
1297
Looks up accounting data for the patron with the given borrowernumber per file number.
1234
    unless ( C4::Context->preference('ManInvInNoissuesCharge') ) {
1298
1235
        my $dbh           = C4::Context->dbh;
1299
C<&GetBorNotifyAcctRecord> returns a three-element array. C<$acctlines> is a
1236
        my $man_inv_types = $dbh->selectcol_arrayref(q{
1300
reference-to-array, where each element is a reference-to-hash; the
1237
            SELECT authorised_value FROM authorised_values WHERE category = 'MANUAL_INV'
1301
keys are the fields of the C<accountlines> table in the Koha database.
1238
        });
1302
C<$count> is the number of elements in C<$acctlines>. C<$total> is the
1239
        push( @not_fines, @$man_inv_types );
1303
total amount outstanding for all of the account lines.
1240
    }
1304
1305
=cut
1306
1241
1307
sub GetBorNotifyAcctRecord {
1242
    my $other_charges =
1308
    my ( $borrowernumber, $notifyid ) = @_;
1243
      Koha::Database->new()->schema->resultset('AccountDebit')->search(
1309
    my $dbh = C4::Context->dbh;
1244
        {
1310
    my @acctlines;
1245
            borrowernumber => $borrowernumber,
1311
    my $numlines = 0;
1246
            type           => { -in => \@not_fines }
1312
    my $sth = $dbh->prepare(
1313
            "SELECT * 
1314
                FROM accountlines 
1315
                WHERE borrowernumber=? 
1316
                    AND notify_id=? 
1317
                    AND amountoutstanding != '0' 
1318
                ORDER BY notify_id,accounttype
1319
                ");
1320
1321
    $sth->execute( $borrowernumber, $notifyid );
1322
    my $total = 0;
1323
    while ( my $data = $sth->fetchrow_hashref ) {
1324
        if ( $data->{itemnumber} ) {
1325
            my $biblio = GetBiblioFromItemNumber( $data->{itemnumber} );
1326
            $data->{biblionumber} = $biblio->{biblionumber};
1327
            $data->{title}        = $biblio->{title};
1328
        }
1247
        }
1329
        $acctlines[$numlines] = $data;
1248
      )->get_column('amount_outstanding')->sum();
1330
        $numlines++;
1249
1331
        $total += int(100 * $data->{'amountoutstanding'});
1250
    return (
1332
    }
1251
        $borrower->account_balance(),
1333
    $total /= 100;
1252
        $borrower->account_balance() - $other_charges,
1334
    return ( $total, \@acctlines, $numlines );
1253
        $other_charges
1254
    );
1335
}
1255
}
1336
1256
1257
1337
=head2 checkuniquemember (OUEST-PROVENCE)
1258
=head2 checkuniquemember (OUEST-PROVENCE)
1338
1259
1339
  ($result,$categorycode)  = &checkuniquemember($collectivity,$surname,$firstname,$dateofbirth);
1260
  ($result,$categorycode)  = &checkuniquemember($collectivity,$surname,$firstname,$dateofbirth);
Lines 2464-2485 Add enrolment fee for a patron if needed. Link Here
2464
2385
2465
sub AddEnrolmentFeeIfNeeded {
2386
sub AddEnrolmentFeeIfNeeded {
2466
    my ( $categorycode, $borrowernumber ) = @_;
2387
    my ( $categorycode, $borrowernumber ) = @_;
2467
    # check for enrollment fee & add it if needed
2388
2468
    my $dbh = C4::Context->dbh;
2389
    my $schema = Koha::Database->new()->schema();
2469
    my $sth = $dbh->prepare(q{
2390
2470
        SELECT enrolmentfee
2391
    my $category = $schema->resultset('Category')->find($categorycode);
2471
        FROM categories
2392
    my $fee      = $category->enrolmentfee();
2472
        WHERE categorycode=?
2393
2473
    });
2394
    if ( $fee && $fee > 0 ) {
2474
    $sth->execute( $categorycode );
2395
        AddDebit(
2475
    if ( $sth->err ) {
2396
            {
2476
        warn sprintf('Database returned the following error: %s', $sth->errstr);
2397
                borrower =>
2477
        return;
2398
                  $schema->resultset('Borrower')->find($borrowernumber),
2478
    }
2399
                type   => Koha::Accounts::DebitTypes::AccountManagementFee(),
2479
    my ($enrolmentfee) = $sth->fetchrow;
2400
                amount => $fee,
2480
    if ($enrolmentfee && $enrolmentfee > 0) {
2401
            }
2481
        # insert fee in patron debts
2402
        );
2482
        C4::Accounts::manualinvoice( $borrowernumber, '', '', 'A', $enrolmentfee );
2483
    }
2403
    }
2484
}
2404
}
2485
2405
(-)a/C4/Overdues.pm (-216 / +143 lines)
Lines 27-35 use List::MoreUtils qw( uniq ); Link Here
27
27
28
use C4::Circulation;
28
use C4::Circulation;
29
use C4::Context;
29
use C4::Context;
30
use C4::Accounts;
31
use C4::Log; # logaction
30
use C4::Log; # logaction
32
use C4::Debug;
31
use C4::Debug;
32
use Koha::Database;
33
use Koha::DateUtils;
34
use Koha::Accounts::OffsetTypes;
35
use Koha::Accounts::DebitTypes;
33
36
34
use vars qw($VERSION @ISA @EXPORT);
37
use vars qw($VERSION @ISA @EXPORT);
35
38
Lines 43-54 BEGIN { Link Here
43
        &CalcFine
46
        &CalcFine
44
        &Getoverdues
47
        &Getoverdues
45
        &checkoverdues
48
        &checkoverdues
46
        &NumberNotifyId
47
        &AmountNotify
48
        &UpdateFine
49
        &UpdateFine
49
        &GetFine
50
        &GetFine
50
        
51
        &CheckItemNotify
52
        &GetOverduesForBranch
51
        &GetOverduesForBranch
53
        &RemoveNotifyLine
52
        &RemoveNotifyLine
54
        &AddNotifyLine
53
        &AddNotifyLine
Lines 463-616 sub GetIssuesIteminfo { Link Here
463
462
464
=head2 UpdateFine
463
=head2 UpdateFine
465
464
466
    &UpdateFine($itemnumber, $borrowernumber, $amount, $type, $description);
465
    UpdateFine(
466
        {
467
            itemnumber     => $itemnumber,
468
            borrowernumber => $borrowernumber,
469
            amount         => $amount,
470
            due            => $due,
471
            issue_id       => $issue_id
472
        }
473
    );
467
474
468
(Note: the following is mostly conjecture and guesswork.)
475
Updates the fine owed on an overdue item.
469
476
470
Updates the fine owed on an overdue book.
477
C<$itemnumber> is the items's id.
471
478
472
C<$itemnumber> is the book's item number.
479
C<$borrowernumber> is the id of the patron who currently
480
has the item on loan.
473
481
474
C<$borrowernumber> is the borrower number of the patron who currently
482
C<$amount> is the total amount of the fine owed by the patron.
475
has the book on loan.
476
483
477
C<$amount> is the current amount owed by the patron.
484
C<&UpdateFine> updates the amount owed for a given fine if an issue_id
485
is passed to it. Otherwise, a new fine will be created.
478
486
479
C<$type> will be used in the description of the fine.
487
=cut
480
488
481
C<$description> is a string that must be present in the description of
489
sub UpdateFine {
482
the fine. I think this is expected to be a date in DD/MM/YYYY format.
490
    my ($params) = @_;
483
491
484
C<&UpdateFine> looks up the amount currently owed on the given item
492
    my $itemnumber     = $params->{itemnumber};
485
and sets it to C<$amount>, creating, if necessary, a new entry in the
493
    my $borrowernumber = $params->{borrowernumber};
486
accountlines table of the Koha database.
494
    my $amount         = $params->{amount};
495
    my $due            = $params->{due};
496
    my $issue_id       = $params->{issue_id};
487
497
488
=cut
498
    my $schema = Koha::Database->new()->schema;
489
499
490
#
500
    my $borrower = $schema->resultset('Borrower')->find($borrowernumber);
491
# Question: Why should the caller have to
501
492
# specify both the item number and the borrower number? A book can't
502
    if ( my $maxfine = C4::Context->preference('MaxFine') ) {
493
# be on loan to two different people, so the item number should be
503
        if ( $borrower->account_balance() + $amount > $maxfine ) {
494
# sufficient.
504
            my $new_amount = $maxfine - $borrower->account_balance();
495
#
505
            warn "Reducing fine for item $itemnumber borrower $borrowernumber from $amount to $new_amount - MaxFine reached";
496
# Possible Answer: You might update a fine for a damaged item, *after* it is returned.
506
            if ( $new_amount <= 0 ) {
497
#
507
                warn "Fine reduced to a non-positive ammount. Fine not created.";
498
sub UpdateFine {
508
                return;
499
    my ( $itemnum, $borrowernumber, $amount, $type, $due ) = @_;
500
	$debug and warn "UpdateFine($itemnum, $borrowernumber, $amount, " . ($type||'""') . ", $due) called";
501
    my $dbh = C4::Context->dbh;
502
    # FIXME - What exactly is this query supposed to do? It looks up an
503
    # entry in accountlines that matches the given item and borrower
504
    # numbers, where the description contains $due, and where the
505
    # account type has one of several values, but what does this _mean_?
506
    # Does it look up existing fines for this item?
507
    # FIXME - What are these various account types? ("FU", "O", "F", "M")
508
	#	"L"   is LOST item
509
	#   "A"   is Account Management Fee
510
	#   "N"   is New Card
511
	#   "M"   is Sundry
512
	#   "O"   is Overdue ??
513
	#   "F"   is Fine ??
514
	#   "FU"  is Fine UPDATE??
515
	#	"Pay" is Payment
516
	#   "REF" is Cash Refund
517
    my $sth = $dbh->prepare(
518
        "SELECT * FROM accountlines
519
        WHERE borrowernumber=?
520
        AND   accounttype IN ('FU','O','F','M')"
521
    );
522
    $sth->execute( $borrowernumber );
523
    my $data;
524
    my $total_amount_other = 0.00;
525
    my $due_qr = qr/$due/;
526
    # Cycle through the fines and
527
    # - find line that relates to the requested $itemnum
528
    # - accumulate fines for other items
529
    # so we can update $itemnum fine taking in account fine caps
530
    while (my $rec = $sth->fetchrow_hashref) {
531
        if ($rec->{itemnumber} == $itemnum && $rec->{description} =~ /$due_qr/) {
532
            if ($data) {
533
                warn "Not a unique accountlines record for item $itemnum borrower $borrowernumber";
534
            } else {
535
                $data = $rec;
536
                next;
537
            }
509
            }
510
            $amount = $new_amount;
538
        }
511
        }
539
        $total_amount_other += $rec->{'amountoutstanding'};
540
    }
512
    }
541
513
542
    if (my $maxfine = C4::Context->preference('MaxFine')) {
514
    my $timestamp = get_timestamp();
543
        if ($total_amount_other + $amount > $maxfine) {
515
544
            my $new_amount = $maxfine - $total_amount_other;
516
    my $fine = $schema->resultset('AccountDebit')->single(
545
            return if $new_amount <= 0.00;
517
        {
546
            warn "Reducing fine for item $itemnum borrower $borrowernumber from $amount to $new_amount - MaxFine reached";
518
            issue_id => $issue_id,
547
            $amount = $new_amount;
519
            type     => Koha::Accounts::DebitTypes::Fine,
520
            accruing => 1,
548
        }
521
        }
549
    }
522
    );
550
523
551
    if ( $data ) {
524
    my $offset = 0;
552
525
    my $credit;
553
		# we're updating an existing fine.  Only modify if amount changed
526
    if ($fine) {
554
        # Note that in the current implementation, you cannot pay against an accruing fine
527
        if ( $fine->accruing() ) { # Don't update or recreate fines no longer accruing
555
        # (i.e. , of accounttype 'FU').  Doing so will break accrual.
528
            if (
556
    	if ( $data->{'amount'} != $amount ) {
529
                sprintf( "%.6f", $fine->amount_original() )
557
            my $diff = $amount - $data->{'amount'};
530
                ne
558
	    #3341: diff could be positive or negative!
531
                sprintf( "%.6f", $amount ) )
559
            my $out  = $data->{'amountoutstanding'} + $diff;
532
            {
560
            my $query = "
533
                my $difference = $amount - $fine->amount_original();
561
                UPDATE accountlines
534
562
				SET date=now(), amount=?, amountoutstanding=?,
535
                # Fine was reduced by a change in circulation rules or another reason
563
					lastincrement=?, accounttype='FU'
536
                # we need to credit the account the difference and zero out the amount outstanding
564
	  			WHERE borrowernumber=?
537
                if ( $difference < 0 ) {
565
				AND   itemnumber=?
538
                    $fine->amount_outstanding( $fine->amount_outstanding() + $difference );
566
				AND   accounttype IN ('FU','O')
539
567
				AND   description LIKE ?
540
                    $credit =
568
				LIMIT 1 ";
541
                      Koha::Database->new()->schema->resultset('AccountCredit')
569
            my $sth2 = $dbh->prepare($query);
542
                      ->create(
570
			# FIXME: BOGUS query cannot ensure uniqueness w/ LIKE %x% !!!
543
                        {
571
			# 		LIMIT 1 added to prevent multiple affected lines
544
                            borrowernumber => $borrowernumber,
572
			# FIXME: accountlines table needs unique key!! Possibly a combo of borrowernumber and accountline.  
545
                            type => Koha::Accounts::CreditTypes::FineReduction(),
573
			# 		But actually, we should just have a regular autoincrementing PK and forget accountline,
546
                            amount_remaining => abs($difference),
574
			# 		including the bogus getnextaccountno function (doesn't prevent conflict on simultaneous ops).
547
                            created_on       => $timestamp,
575
			# FIXME: Why only 2 account types here?
548
                        }
576
			$debug and print STDERR "UpdateFine query: $query\n" .
549
                      );
577
				"w/ args: $amount, $out, $diff, $data->{'borrowernumber'}, $data->{'itemnumber'}, \"\%$due\%\"\n";
550
578
            $sth2->execute($amount, $out, $diff, $data->{'borrowernumber'}, $data->{'itemnumber'}, "%$due%");
551
                } else {
579
        } else {
552
                    $fine->amount_outstanding( $amount );
580
            #      print "no update needed $data->{'amount'}"
553
                }
554
555
                $fine->amount_last_increment($difference);
556
                $fine->amount_original( $fine->amount_original() + $difference );
557
                $fine->updated_on($timestamp);
558
                $fine->update();
559
560
                $offset = 1;
561
            }
581
        }
562
        }
582
    } else {
563
    }
583
        my $sth4 = $dbh->prepare(
564
    elsif ( $amount ) { # No fine to update, don't insert fines of $0.00
584
            "SELECT title FROM biblio LEFT JOIN items ON biblio.biblionumber=items.biblionumber WHERE items.itemnumber=?"
565
        my $item = $schema->resultset('Item')->find($itemnumber);
566
567
        $fine = $schema->resultset('AccountDebit')->create(
568
            {
569
                borrowernumber        => $borrowernumber,
570
                itemnumber            => $itemnumber,
571
                issue_id              => $issue_id,
572
                type                  => Koha::Accounts::DebitTypes::Fine(),
573
                accruing              => 1,
574
                amount_original       => $amount,
575
                amount_outstanding    => $amount,
576
                amount_last_increment => $amount,
577
                description           => $item->biblio()->title() . " / Due:$due",
578
                created_on            => $timestamp,
579
            }
585
        );
580
        );
586
        $sth4->execute($itemnum);
581
587
        my $title = $sth4->fetchrow;
582
        $offset = 1;
588
583
    } else { # No fine to update, amount is 0, just return
589
#         #   print "not in account";
584
        return;
590
#         my $sth3 = $dbh->prepare("Select max(accountno) from accountlines");
591
#         $sth3->execute;
592
# 
593
#         # FIXME - Make $accountno a scalar.
594
#         my @accountno = $sth3->fetchrow_array;
595
#         $sth3->finish;
596
#         $accountno[0]++;
597
# begin transaction
598
		my $nextaccntno = C4::Accounts::getnextacctno($borrowernumber);
599
		my $desc = ($type ? "$type " : '') . "$title $due";	# FIXEDME, avoid whitespace prefix on empty $type
600
		my $query = "INSERT INTO accountlines
601
		    (borrowernumber,itemnumber,date,amount,description,accounttype,amountoutstanding,lastincrement,accountno)
602
			    VALUES (?,?,now(),?,?,'FU',?,?,?)";
603
		my $sth2 = $dbh->prepare($query);
604
		$debug and print STDERR "UpdateFine query: $query\nw/ args: $borrowernumber, $itemnum, $amount, $desc, $amount, $amount, $nextaccntno\n";
605
        $sth2->execute($borrowernumber, $itemnum, $amount, $desc, $amount, $amount, $nextaccntno);
606
    }
585
    }
607
    # logging action
586
608
    &logaction(
587
    $schema->resultset('AccountOffset')->create(
609
        "FINES",
588
        {
610
        $type,
589
            debit_id   => $fine->debit_id(),
590
            credit_id  => $credit ? $credit->credit_id() : undef,
591
            amount     => $fine->amount_last_increment(),
592
            created_on => $timestamp,
593
            type       => Koha::Accounts::OffsetTypes::Fine(),
594
        }
595
    ) if $offset;
596
597
    $borrower->account_balance( $borrower->account_balance + $fine->amount_last_increment() );
598
    $borrower->update();
599
600
    logaction( "FINES", Koha::Accounts::DebitTypes::Fine(),
611
        $borrowernumber,
601
        $borrowernumber,
612
        "due=".$due."  amount=".$amount." itemnumber=".$itemnum
602
        "due=" . $due . "  amount=" . $amount . " itemnumber=" . $itemnumber )
613
        ) if C4::Context->preference("FinesLog");
603
      if C4::Context->preference("FinesLog");
614
}
604
}
615
605
616
=head2 BorType
606
=head2 BorType
Lines 665-720 sub GetFine { Link Here
665
    return 0;
655
    return 0;
666
}
656
}
667
657
668
=head2 NumberNotifyId
669
670
    (@notify) = &NumberNotifyId($borrowernumber);
671
672
Returns amount for all file per borrowers
673
C<@notify> array contains all file per borrowers
674
675
C<$notify_id> contains the file number for the borrower number nad item number
676
677
=cut
678
679
sub NumberNotifyId{
680
    my ($borrowernumber)=@_;
681
    my $dbh = C4::Context->dbh;
682
    my $query=qq|    SELECT distinct(notify_id)
683
            FROM accountlines
684
            WHERE borrowernumber=?|;
685
    my @notify;
686
    my $sth = $dbh->prepare($query);
687
    $sth->execute($borrowernumber);
688
    while ( my ($numberofnotify) = $sth->fetchrow ) {
689
        push( @notify, $numberofnotify );
690
    }
691
    return (@notify);
692
}
693
694
=head2 AmountNotify
695
658
696
    ($totalnotify) = &AmountNotify($notifyid);
659
=head2 NumberNotifyId
697
698
Returns amount for all file per borrowers
699
C<$notifyid> is the file number
700
701
C<$totalnotify> contains amount of a file
702
660
703
C<$notify_id> contains the file number for the borrower number and item number
661
    my $schema = Koha::Database->new()->schema;
704
662
705
=cut
663
    my $amount_outstanding = $schema->resultset('AccountDebit')->search(
664
        {
665
            itemnumber     => $itemnumber,
666
            borrowernumber => $borrowernumber,
667
            type           => Koha::Accounts::DebitTypes::Fine(),
668
        },
669
    )->get_column('amount_outstanding')->sum();
706
670
707
sub AmountNotify{
671
    return $amount_outstanding;
708
    my ($notifyid,$borrowernumber)=@_;
709
    my $dbh = C4::Context->dbh;
710
    my $query=qq|    SELECT sum(amountoutstanding)
711
            FROM accountlines
712
            WHERE notify_id=? AND borrowernumber = ?|;
713
    my $sth=$dbh->prepare($query);
714
	$sth->execute($notifyid,$borrowernumber);
715
	my $totalnotify=$sth->fetchrow;
716
    $sth->finish;
717
    return ($totalnotify);
718
}
672
}
719
673
720
=head2 GetItems
674
=head2 GetItems
Lines 770-796 sub GetBranchcodesWithOverdueRules { Link Here
770
    return @$branchcodes;
724
    return @$branchcodes;
771
}
725
}
772
726
773
=head2 CheckItemNotify
774
775
Sql request to check if the document has alreday been notified
776
this function is not exported, only used with GetOverduesForBranch
777
778
=cut
779
780
sub CheckItemNotify {
781
    my ($notify_id,$notify_level,$itemnumber) = @_;
782
    my $dbh = C4::Context->dbh;
783
    my $sth = $dbh->prepare("
784
    SELECT COUNT(*)
785
     FROM notifys
786
    WHERE notify_id    = ?
787
     AND  notify_level = ? 
788
     AND  itemnumber   = ? ");
789
    $sth->execute($notify_id,$notify_level,$itemnumber);
790
    my $notified = $sth->fetchrow;
791
    return ($notified);
792
}
793
794
=head2 GetOverduesForBranch
727
=head2 GetOverduesForBranch
795
728
796
Sql request for display all information for branchoverdues.pl
729
Sql request for display all information for branchoverdues.pl
Lines 816-821 sub GetOverduesForBranch { Link Here
816
               biblio.title,
749
               biblio.title,
817
               biblio.author,
750
               biblio.author,
818
               biblio.biblionumber,
751
               biblio.biblionumber,
752
               issues.issue_id,
819
               issues.date_due,
753
               issues.date_due,
820
               issues.returndate,
754
               issues.returndate,
821
               issues.branchcode,
755
               issues.branchcode,
Lines 826-850 sub GetOverduesForBranch { Link Here
826
                items.location,
760
                items.location,
827
                items.itemnumber,
761
                items.itemnumber,
828
            itemtypes.description,
762
            itemtypes.description,
829
         accountlines.notify_id,
763
            account_debits.amount_outstanding
830
         accountlines.notify_level,
764
    FROM  account_debits
831
         accountlines.amountoutstanding
765
    LEFT JOIN issues      ON    issues.itemnumber     = account_debits.itemnumber
832
    FROM  accountlines
766
                          AND   issues.borrowernumber = account_debits.borrowernumber
833
    LEFT JOIN issues      ON    issues.itemnumber     = accountlines.itemnumber
767
    LEFT JOIN borrowers   ON borrowers.borrowernumber = account_debits.borrowernumber
834
                          AND   issues.borrowernumber = accountlines.borrowernumber
835
    LEFT JOIN borrowers   ON borrowers.borrowernumber = accountlines.borrowernumber
836
    LEFT JOIN items       ON     items.itemnumber     = issues.itemnumber
768
    LEFT JOIN items       ON     items.itemnumber     = issues.itemnumber
837
    LEFT JOIN biblio      ON      biblio.biblionumber =  items.biblionumber
769
    LEFT JOIN biblio      ON      biblio.biblionumber =  items.biblionumber
838
    LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber
770
    LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber
839
    LEFT JOIN itemtypes   ON itemtypes.itemtype       = $itype_link
771
    LEFT JOIN itemtypes   ON itemtypes.itemtype       = $itype_link
840
    LEFT JOIN branches    ON  branches.branchcode     = issues.branchcode
772
    LEFT JOIN branches    ON  branches.branchcode     = issues.branchcode
841
    WHERE (accountlines.amountoutstanding  != '0.000000')
773
    WHERE (account_debits.amount_outstanding  != '0.000000')
842
      AND (accountlines.accounttype         = 'FU'      )
774
      AND (account_debits.type = 'FINE')
775
      AND (account_debits.accruing = 1 )
843
      AND (issues.branchcode =  ?   )
776
      AND (issues.branchcode =  ?   )
844
      AND (issues.date_due  < NOW())
777
      AND (issues.date_due  < NOW())
845
    ";
778
    ";
846
    my @getoverdues;
779
    my @getoverdues;
847
    my $i = 0;
848
    my $sth;
780
    my $sth;
849
    if ($location) {
781
    if ($location) {
850
        $sth = $dbh->prepare("$select AND items.location = ? ORDER BY borrowers.surname, borrowers.firstname");
782
        $sth = $dbh->prepare("$select AND items.location = ? ORDER BY borrowers.surname, borrowers.firstname");
Lines 854-865 sub GetOverduesForBranch { Link Here
854
        $sth->execute($branch);
786
        $sth->execute($branch);
855
    }
787
    }
856
    while ( my $data = $sth->fetchrow_hashref ) {
788
    while ( my $data = $sth->fetchrow_hashref ) {
857
    #check if the document has already been notified
789
        push( @getoverdues, $data );
858
        my $countnotify = CheckItemNotify($data->{'notify_id'}, $data->{'notify_level'}, $data->{'itemnumber'});
859
        if ($countnotify eq '0') {
860
            $getoverdues[$i] = $data;
861
            $i++;
862
        }
863
    }
790
    }
864
    return (@getoverdues);
791
    return (@getoverdues);
865
}
792
}
(-)a/C4/Reports/Guided.pm (-1 / +1 lines)
Lines 99-105 sub get_table_areas { Link Here
99
    CAT  => [ 'items', 'biblioitems', 'biblio' ],
99
    CAT  => [ 'items', 'biblioitems', 'biblio' ],
100
    PAT  => ['borrowers'],
100
    PAT  => ['borrowers'],
101
    ACQ  => [ 'aqorders', 'biblio', 'items' ],
101
    ACQ  => [ 'aqorders', 'biblio', 'items' ],
102
    ACC  => [ 'borrowers', 'accountlines' ],
102
    ACC  => [ 'borrowers', 'account_credits', 'account_debits' ],
103
    );
103
    );
104
}
104
}
105
105
(-)a/C4/Reserves.pm (-13 / +10 lines)
Lines 28-34 use C4::Biblio; Link Here
28
use C4::Members;
28
use C4::Members;
29
use C4::Items;
29
use C4::Items;
30
use C4::Circulation;
30
use C4::Circulation;
31
use C4::Accounts;
32
31
33
# for _koha_notify_reserve
32
# for _koha_notify_reserve
34
use C4::Members::Messaging;
33
use C4::Members::Messaging;
Lines 175-193 sub AddReserve { Link Here
175
        $waitingdate = $resdate;
174
        $waitingdate = $resdate;
176
    }
175
    }
177
176
178
    #eval {
179
    # updates take place here
180
    if ( $fee > 0 ) {
177
    if ( $fee > 0 ) {
181
        my $nextacctno = &getnextacctno( $borrowernumber );
178
        AddDebit(
182
        my $query      = qq/
179
            {
183
        INSERT INTO accountlines
180
                borrowernumber => $borrowernumber,
184
            (borrowernumber,accountno,date,amount,description,accounttype,amountoutstanding)
181
                itemnumber     => $checkitem,
185
        VALUES
182
                amount         => $fee,
186
            (?,?,now(),?,?,'Res',?)
183
                type           => Koha::Accounts::DebitTypes::Hold(),
187
    /;
184
                description    => "Hold fee - $title",
188
        my $usth = $dbh->prepare($query);
185
                notes          => "Record ID: $biblionumber",
189
        $usth->execute( $borrowernumber, $nextacctno, $fee,
186
            }
190
            "Reserve Charge - $title", $fee );
187
        );
191
    }
188
    }
192
189
193
    #if ($const eq 'a'){
190
    #if ($const eq 'a'){
(-)a/C4/SIP/ILS/Patron.pm (-1 / +2 lines)
Lines 87-93 sub new { Link Here
87
        hold_ok         => ( !$debarred && !$expired && !$fine_blocked),
87
        hold_ok         => ( !$debarred && !$expired && !$fine_blocked),
88
        card_lost       => ( $kp->{lost} || $kp->{gonenoaddress} || $flags->{LOST} ),
88
        card_lost       => ( $kp->{lost} || $kp->{gonenoaddress} || $flags->{LOST} ),
89
        claims_returned => 0,
89
        claims_returned => 0,
90
        fines           => $fines_amount, # GetMemberAccountRecords($kp->{borrowernumber})
90
        fines           => $fines_amount,
91
        fees            => 0,             # currently not distinct from fines
91
        fees            => 0,             # currently not distinct from fines
92
        recall_overdue  => 0,
92
        recall_overdue  => 0,
93
        items_billed    => 0,
93
        items_billed    => 0,
Lines 102-107 sub new { Link Here
102
        inet            => ( !$debarred && !$expired ),
102
        inet            => ( !$debarred && !$expired ),
103
        expired         => $expired,
103
        expired         => $expired,
104
        fee_limit       => $fee_limit,
104
        fee_limit       => $fee_limit,
105
        account_balance => $kp->{account_balance},
105
    );
106
    );
106
    }
107
    }
107
    $debug and warn "patron fines: $ilspatron{fines} ... amountoutstanding: $kp->{amountoutstanding} ... CHARGES->amount: $flags->{CHARGES}->{amount}";
108
    $debug and warn "patron fines: $ilspatron{fines} ... amountoutstanding: $kp->{amountoutstanding} ... CHARGES->amount: $flags->{CHARGES}->{amount}";
(-)a/C4/SIP/ILS/Transaction/FeePayment.pm (-4 / +15 lines)
Lines 20-26 use strict; Link Here
20
# with Koha; if not, write to the Free Software Foundation, Inc.,
20
# with Koha; if not, write to the Free Software Foundation, Inc.,
21
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22
22
23
use C4::Accounts qw(recordpayment);
23
use Koha::Accounts qw(AddCredit);
24
use Koha::Accounts::CreditTypes;
25
use Koha::Database;
24
use ILS;
26
use ILS;
25
use parent qw(ILS::Transaction);
27
use parent qw(ILS::Transaction);
26
28
Lines 45-54 sub new { Link Here
45
sub pay {
47
sub pay {
46
    my $self           = shift;
48
    my $self           = shift;
47
    my $borrowernumber = shift;
49
    my $borrowernumber = shift;
48
    my $amt            = shift;
50
    my $amount         = shift;
49
    my $type           = shift;
51
    my $type           = shift;
50
    warn("RECORD:$borrowernumber::$amt");
52
51
    recordpayment( $borrowernumber, $amt,$type );
53
    warn("RECORD:$borrowernumber::$amount");
54
55
    AddCredit(
56
        {
57
            borrower => Koha::Database->new()->schema->resultset('Borrower')->find($borrowernumber),
58
            amount => $amount,
59
            notes  => "via SIP2. Type:$type",
60
            type   => Koha::Accounts::CreditTypes::Payment,
61
        }
62
    );
52
}
63
}
53
64
54
#sub DESTROY {
65
#sub DESTROY {
(-)a/C4/SIP/ILS/Transaction/Renew.pm (+6 lines)
Lines 34-39 sub do_renew_for { Link Here
34
    my $self = shift;
34
    my $self = shift;
35
    my $borrower = shift;
35
    my $borrower = shift;
36
    my ($renewokay,$renewerror) = CanBookBeRenewed($borrower->{borrowernumber},$self->{item}->{itemnumber});
36
    my ($renewokay,$renewerror) = CanBookBeRenewed($borrower->{borrowernumber},$self->{item}->{itemnumber});
37
38
    unless ( $borrower->{account_balance} < C4::Context->preference('OPACFineNoRenewals') ) {
39
        $renewokay = 0;
40
        $renewerror = 'too_many_fines'
41
    }
42
37
    if ($renewokay){
43
    if ($renewokay){
38
        $self->{due} = undef;
44
        $self->{due} = undef;
39
        my $due_date = AddIssue( $borrower, $self->{item}->id, undef, 0 );
45
        my $due_date = AddIssue( $borrower, $self->{item}->id, undef, 0 );
(-)a/Koha/DateUtils.pm (-1 / +6 lines)
Lines 21-33 use warnings; Link Here
21
use 5.010;
21
use 5.010;
22
use DateTime;
22
use DateTime;
23
use DateTime::Format::DateParse;
23
use DateTime::Format::DateParse;
24
use DateTime::Format::MySQL;
24
use C4::Context;
25
use C4::Context;
25
26
26
use base 'Exporter';
27
use base 'Exporter';
27
use version; our $VERSION = qv('1.0.0');
28
use version; our $VERSION = qv('1.0.0');
28
29
29
our @EXPORT = (
30
our @EXPORT = (
30
    qw( dt_from_string output_pref format_sqldatetime )
31
    qw( dt_from_string output_pref format_sqldatetime get_timestamp )
31
);
32
);
32
33
33
=head1 DateUtils
34
=head1 DateUtils
Lines 190-193 sub format_sqldatetime { Link Here
190
    return q{};
191
    return q{};
191
}
192
}
192
193
194
sub get_timestamp {
195
    return DateTime::Format::MySQL->format_datetime( dt_from_string() );
196
}
197
193
1;
198
1;
(-)a/Koha/Template/Plugin/AuthorisedValues.pm (+2 lines)
Lines 74-76 Kyle M Hall <kyle@bywatersolutions.com> Link Here
74
Jonathan Druart <jonathan.druart@biblibre.com>
74
Jonathan Druart <jonathan.druart@biblibre.com>
75
75
76
=cut
76
=cut
77
78
1;
(-)a/Koha/Template/Plugin/Koha.pm (-1 / +5 lines)
Lines 44-47 sub Preference { Link Here
44
    return C4::Context->preference( $pref );
44
    return C4::Context->preference( $pref );
45
}
45
}
46
46
47
sub Get {
48
    my ( $self, $category, $selected, $opac ) = @_;
49
    return GetAuthorisedValues( $category, $selected, $opac );
50
}
51
47
1;
52
1;
48
- 

Return to bug 6427