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

(-)a/Koha/Account.pm (-215 / +20 lines)
Lines 81-312 sub pay { Link Here
81
    my $lines         = $params->{lines};
81
    my $lines         = $params->{lines};
82
    my $type          = $params->{type} || 'PAYMENT';
82
    my $type          = $params->{type} || 'PAYMENT';
83
    my $payment_type  = $params->{payment_type} || undef;
83
    my $payment_type  = $params->{payment_type} || undef;
84
    my $credit_type   = $params->{credit_type};
85
    my $offset_type   = $params->{offset_type} || $type eq 'WRITEOFF' ? 'Writeoff' : 'Payment';
84
    my $offset_type   = $params->{offset_type} || $type eq 'WRITEOFF' ? 'Writeoff' : 'Payment';
86
    my $cash_register = $params->{cash_register};
85
    my $cash_register = $params->{cash_register};
87
    my $item_id       = $params->{item_id};
86
    my $item_id       = $params->{item_id};
88
87
89
    my $userenv = C4::Context->userenv;
88
    my $userenv = C4::Context->userenv;
90
89
91
    $credit_type ||=
92
      $type eq 'WRITEOFF'
93
      ? 'WRITEOFF'
94
      : 'PAYMENT';
95
96
    my $patron = Koha::Patrons->find( $self->{patron_id} );
97
90
98
    my $manager_id = $userenv ? $userenv->{number} : undef;
91
    my $manager_id = $userenv ? $userenv->{number} : undef;
99
    my $interface = $params ? ( $params->{interface} || C4::Context->interface ) : C4::Context->interface;
92
    my $interface = $params ? ( $params->{interface} || C4::Context->interface ) : C4::Context->interface;
100
    Koha::Exceptions::Account::RegisterRequired->throw()
93
    my $payment = $self->payin_amount(
101
      if ( C4::Context->preference("UseCashRegisters")
102
        && defined($payment_type)
103
        && ( $payment_type eq 'CASH' )
104
        && !defined($cash_register) );
105
106
    my @fines_paid; # List of account lines paid on with this payment
107
108
    # The outcome of any attempted item renewals as a result of fines being
109
    # paid off
110
    my $renew_outcomes = [];
111
112
    my $balance_remaining = $amount; # Set it now so we can adjust the amount if necessary
113
    $balance_remaining ||= 0;
114
115
    my @account_offsets;
116
117
    # We were passed a specific line to pay
118
    foreach my $fine ( @$lines ) {
119
        my $amount_to_pay =
120
            $fine->amountoutstanding > $balance_remaining
121
          ? $balance_remaining
122
          : $fine->amountoutstanding;
123
124
        my $old_amountoutstanding = $fine->amountoutstanding;
125
        my $new_amountoutstanding = $old_amountoutstanding - $amount_to_pay;
126
        $fine->amountoutstanding($new_amountoutstanding)->store();
127
        $balance_remaining = $balance_remaining - $amount_to_pay;
128
129
        # Attempt to renew the item associated with this debit if
130
        # appropriate
131
        if ($fine->is_renewable) {
132
            # We're ignoring the definition of $interface above, by all
133
            # accounts we can't rely on C4::Context::interface, so here
134
            # we're only using what we've been explicitly passed
135
            my $outcome = $fine->renew_item({ interface => $interface });
136
            push @{$renew_outcomes}, $outcome if $outcome;
137
        }
138
139
        # Same logic exists in Koha::Account::Line::apply
140
        if ( C4::Context->preference('MarkLostItemsAsReturned') =~ m|onpayment|
141
            && $fine->debit_type_code
142
            && $fine->debit_type_code eq 'LOST'
143
            && $new_amountoutstanding == 0
144
            && $fine->itemnumber
145
            && !(  $credit_type eq 'LOST_FOUND'
146
                && $item_id == $fine->itemnumber ) )
147
        {
148
            C4::Circulation::ReturnLostItem( $self->{patron_id},
149
                $fine->itemnumber );
150
        }
151
152
        my $account_offset = Koha::Account::Offset->new(
153
            {
154
                debit_id => $fine->id,
155
                type     => $offset_type,
156
                amount   => $amount_to_pay * -1,
157
            }
158
        );
159
        push( @account_offsets, $account_offset );
160
161
        if ( C4::Context->preference("FinesLog") ) {
162
            logaction(
163
                "FINES", 'MODIFY',
164
                $self->{patron_id},
165
                Dumper(
166
                    {
167
                        action                => 'fee_payment',
168
                        borrowernumber        => $fine->borrowernumber,
169
                        old_amountoutstanding => $old_amountoutstanding,
170
                        new_amountoutstanding => 0,
171
                        amount_paid           => $old_amountoutstanding,
172
                        accountlines_id       => $fine->id,
173
                        manager_id            => $manager_id,
174
                        note                  => $note,
175
                    }
176
                ),
177
                $interface
178
            );
179
            push( @fines_paid, $fine->id );
180
        }
181
    }
182
183
    # Were not passed a specific line to pay, or the payment was for more
184
    # than the what was owed on the given line. In that case pay down other
185
    # lines with remaining balance.
186
    my @outstanding_fines;
187
    @outstanding_fines = $self->lines->search(
188
        {
189
            amountoutstanding => { '>' => 0 },
190
        }
191
    ) if $balance_remaining > 0;
192
193
    foreach my $fine (@outstanding_fines) {
194
        my $amount_to_pay =
195
            $fine->amountoutstanding > $balance_remaining
196
          ? $balance_remaining
197
          : $fine->amountoutstanding;
198
199
        my $old_amountoutstanding = $fine->amountoutstanding;
200
        $fine->amountoutstanding( $old_amountoutstanding - $amount_to_pay );
201
        $fine->store();
202
203
        # If we need to make a note of the item associated with this line,
204
        # in order that we can potentially renew it, do so.
205
        my $amt = $old_amountoutstanding - $amount_to_pay;
206
        if ( $fine->is_renewable ) {
207
            my $outcome = $fine->renew_item({ interface => $interface });
208
            push @{$renew_outcomes}, $outcome if $outcome;
209
        }
210
211
        if ( C4::Context->preference('MarkLostItemsAsReturned') =~ m|onpayment|
212
            && $fine->debit_type_code
213
            && $fine->debit_type_code eq 'LOST'
214
            && $fine->amountoutstanding == 0
215
            && $fine->itemnumber
216
            && !(  $credit_type eq 'LOST_FOUND'
217
                && $item_id == $fine->itemnumber ) )
218
        {
94
        {
219
            C4::Circulation::ReturnLostItem( $self->{patron_id},
95
            interface     => $interface,
220
                $fine->itemnumber );
96
            type          => $type,
221
        }
97
            amount        => $amount,
222
98
            payment_type  => $payment_type,
223
        my $account_offset = Koha::Account::Offset->new(
99
            cash_register => $cash_register,
224
            {
100
            user_id       => $manager_id,
225
                debit_id => $fine->id,
101
            library_id    => $library_id,
226
                type     => $offset_type,
102
            item_id       => $item_id,
227
                amount   => $amount_to_pay * -1,
103
            description   => $description,
228
            }
104
            note          => $note,
229
        );
105
            debits        => $lines
230
        push( @account_offsets, $account_offset );
231
232
        if ( C4::Context->preference("FinesLog") ) {
233
            logaction(
234
                "FINES", 'MODIFY',
235
                $self->{patron_id},
236
                Dumper(
237
                    {
238
                        action                => "fee_$type",
239
                        borrowernumber        => $fine->borrowernumber,
240
                        old_amountoutstanding => $old_amountoutstanding,
241
                        new_amountoutstanding => $fine->amountoutstanding,
242
                        amount_paid           => $amount_to_pay,
243
                        accountlines_id       => $fine->id,
244
                        manager_id            => $manager_id,
245
                        note                  => $note,
246
                    }
247
                ),
248
                $interface
249
            );
250
            push( @fines_paid, $fine->id );
251
        }
252
253
        $balance_remaining = $balance_remaining - $amount_to_pay;
254
        last unless $balance_remaining > 0;
255
    }
256
257
    $description ||= $type eq 'WRITEOFF' ? 'Writeoff' : q{};
258
259
    my $payment = Koha::Account::Line->new(
260
        {
261
            borrowernumber    => $self->{patron_id},
262
            date              => dt_from_string(),
263
            amount            => 0 - $amount,
264
            description       => $description,
265
            credit_type_code  => $credit_type,
266
            payment_type      => $payment_type,
267
            amountoutstanding => 0 - $balance_remaining,
268
            manager_id        => $manager_id,
269
            interface         => $interface,
270
            branchcode        => $library_id,
271
            register_id       => $cash_register,
272
            note              => $note,
273
            itemnumber        => $item_id,
274
        }
275
    )->store();
276
277
    foreach my $o ( @account_offsets ) {
278
        $o->credit_id( $payment->id() );
279
        $o->store();
280
    }
281
282
    C4::Stats::UpdateStats(
283
        {
284
            branch         => $library_id,
285
            type           => lc($type),
286
            amount         => $amount,
287
            borrowernumber => $self->{patron_id},
288
        }
106
        }
289
    );
107
    );
290
108
291
    if ( C4::Context->preference("FinesLog") ) {
109
    my $patron = Koha::Patrons->find( $self->{patron_id} );
292
        logaction(
110
    my @account_offsets = $payment->debit_offsets;
293
            "FINES", 'CREATE',
294
            $self->{patron_id},
295
            Dumper(
296
                {
297
                    action            => "create_$type",
298
                    borrowernumber    => $self->{patron_id},
299
                    amount            => 0 - $amount,
300
                    amountoutstanding => 0 - $balance_remaining,
301
                    credit_type_code  => $credit_type,
302
                    accountlines_paid => \@fines_paid,
303
                    manager_id        => $manager_id,
304
                }
305
            ),
306
            $interface
307
        );
308
    }
309
310
    if ( C4::Context->preference('UseEmailReceipts') ) {
111
    if ( C4::Context->preference('UseEmailReceipts') ) {
311
        if (
112
        if (
312
            my $letter = C4::Letters::GetPreparedLetter(
113
            my $letter = C4::Letters::GetPreparedLetter(
Lines 335-340 sub pay { Link Here
335
        }
136
        }
336
    }
137
    }
337
138
139
    my $renew_outcomes = [];
140
    for my $message ( @{$payment->messages} ) {
141
        push @{$renew_outcomes}, $message->payload;
142
    }
143
338
    return { payment_id => $payment->id, renew_result => $renew_outcomes };
144
    return { payment_id => $payment->id, renew_result => $renew_outcomes };
339
}
145
}
340
146
Lines 490-496 sub add_credit { Link Here
490
    my $credit = $account->payin_amount(
296
    my $credit = $account->payin_amount(
491
        {
297
        {
492
            amount          => $amount,
298
            amount          => $amount,
493
            credit_type     => $credit_type,
299
            type            => $credit_type,
494
            payment_type    => $payment_type,
300
            payment_type    => $payment_type,
495
            cash_register   => $register_id,
301
            cash_register   => $register_id,
496
            interface       => $interface,
302
            interface       => $interface,
497
- 

Return to bug 27636