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

(-)a/Koha/Account/Line.pm (-56 / +65 lines)
Lines 632-704 sub apply { Link Here
632
632
633
    my $schema = Koha::Database->new->schema;
633
    my $schema = Koha::Database->new->schema;
634
634
635
    $schema->txn_do( sub {
635
    $schema->txn_do(
636
        for my $debit ( @{$debits} ) {
636
        sub {
637
            for my $debit ( @{$debits} ) {
637
638
638
            unless ( $debit->is_debit ) {
639
                unless ( $debit->is_debit ) {
639
                Koha::Exceptions::Account::IsNotDebit->throw(
640
                    Koha::Exceptions::Account::IsNotDebit->throw(
640
                    error => 'Account line ' . $debit->id . 'is not a debit'
641
                        error => 'Account line ' . $debit->id . 'is not a debit' );
641
                );
642
                }
642
            }
643
                my $amount_to_cancel;
643
            my $amount_to_cancel;
644
                my $owed = $debit->amountoutstanding;
644
            my $owed = $debit->amountoutstanding;
645
645
646
            if ( $available_credit >= $owed ) {
646
                if ( $available_credit >= $owed ) {
647
                $amount_to_cancel = $owed;
647
                    $amount_to_cancel = $owed;
648
            }
648
                } else {    # $available_credit < $debit->amountoutstanding
649
            else {    # $available_credit < $debit->amountoutstanding
649
                    $amount_to_cancel = $available_credit;
650
                $amount_to_cancel = $available_credit;
650
                }
651
            }
652
651
653
            # record the account offset
652
                # record the account offset
654
            Koha::Account::Offset->new(
653
                Koha::Account::Offset->new(
655
                {   credit_id => $self->id,
654
                    {
656
                    debit_id  => $debit->id,
655
                        credit_id => $self->id,
657
                    amount    => $amount_to_cancel * -1,
656
                        debit_id  => $debit->id,
658
                    type      => 'APPLY'
657
                        amount    => $amount_to_cancel * -1,
658
                        type      => 'APPLY'
659
                    }
660
                )->store();
661
662
                $available_credit -= $amount_to_cancel;
663
664
                $self->amountoutstanding( $available_credit * -1 )->store;
665
                $debit->amountoutstanding( $owed - $amount_to_cancel )->store;
666
667
                # Attempt to renew the item associated with this debit if
668
                # appropriate
669
                if ( $self->credit_type_code ne 'FORGIVEN' && $debit->is_renewable ) {
670
                    my $outcome = $debit->renew_item( { interface => $params->{interface} } );
671
                    $self->add_message(
672
                        {
673
                            type    => 'info',
674
                            message => 'renewal',
675
                            payload => $outcome
676
                        }
677
                    ) if $outcome;
659
                }
678
                }
660
            )->store();
679
                $debit->discard_changes;    # Refresh values from DB to clear floating point remainders
661
680
662
            $available_credit -= $amount_to_cancel;
681
                if (   $debit->debit_type_code
682
                    && $debit->debit_type_code eq 'LOST'
683
                    && $debit->amountoutstanding == 0
684
                    && $debit->itemnumber
685
                    && !( $self->credit_type_code eq 'LOST_FOUND' && $self->itemnumber == $debit->itemnumber ) )
686
                {
663
687
664
            $self->amountoutstanding( $available_credit * -1 )->store;
688
                    if ( C4::Context->preference('UpdateItemLostStatusWhenPaid')
665
            $debit->amountoutstanding( $owed - $amount_to_cancel )->store;
689
                        && !( $self->credit_type_code eq 'WRITEOFF' || $self->credit_type_code eq 'VOID' ) )
690
                    {
691
                        $debit->item->itemlost( C4::Context->preference('UpdateItemLostStatusWhenPaid') )->store();
692
                    }
666
693
667
            # Attempt to renew the item associated with this debit if
694
                    if ( C4::Context->preference('UpdateItemLostStatusWhenWriteOff')
668
            # appropriate
695
                        && ( $self->credit_type_code eq 'WRITEOFF' || $self->credit_type_code eq 'VOID' ) )
669
            if ( $self->credit_type_code ne 'FORGIVEN' && $debit->is_renewable ) {
670
                my $outcome = $debit->renew_item( { interface => $params->{interface} } );
671
                $self->add_message(
672
                    {
696
                    {
673
                        type    => 'info',
697
                        $debit->item->itemlost( C4::Context->preference('UpdateItemLostStatusWhenWriteOff') )->store();
674
                        message => 'renewal',
675
                        payload => $outcome
676
                    }
698
                    }
677
                ) if $outcome;
678
            }
679
            $debit->discard_changes; # Refresh values from DB to clear floating point remainders
680
681
            # Same logic exists in Koha::Account::pay
682
            if (
683
                C4::Context->preference('MarkLostItemsAsReturned') =~
684
                m|onpayment|
685
                && $debit->debit_type_code
686
                && $debit->debit_type_code eq 'LOST'
687
                && $debit->amountoutstanding == 0
688
                && $debit->itemnumber
689
                && !(
690
                       $self->credit_type_code eq 'LOST_FOUND'
691
                    && $self->itemnumber == $debit->itemnumber
692
                )
693
              )
694
            {
695
                C4::Circulation::ReturnLostItem( $self->borrowernumber,
696
                    $debit->itemnumber );
697
            }
698
699
699
            last if $available_credit == 0;
700
                    if ( C4::Context->preference('MarkLostItemsAsReturned') =~ m|onpayment| ) {
701
                        C4::Circulation::ReturnLostItem(
702
                            $self->borrowernumber,
703
                            $debit->itemnumber
704
                        );
705
                    }
706
                }
707
                last if $available_credit == 0;
708
            }
700
        }
709
        }
701
    });
710
    );
702
711
703
    Koha::Patron::Debarments::del_restrictions_after_payment( { borrowernumber => $self->borrowernumber } );
712
    Koha::Patron::Debarments::del_restrictions_after_payment( { borrowernumber => $self->borrowernumber } );
704
713
(-)a/installer/data/mysql/atomicupdate/bug_22740-add_UpdateItemLostStatusWhenPaid_syspref.pl (+27 lines)
Line 0 Link Here
1
use Modern::Perl;
2
3
return {
4
    bug_number  => "22740",
5
    description =>
6
        "Preferences to enable automated setting of lost status when the associated fine is paid or written off",
7
    up => sub {
8
        my ($args) = @_;
9
        my ( $dbh, $out ) = @$args{qw(dbh out)};
10
11
        # Do you stuffs here
12
        # sysprefs
13
        $dbh->do(
14
            q{
15
                INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type) VALUES ('UpdateItemLostStatusWhenPaid', '0', NULL, 'Allows the status of lost items to be automatically changed when item paid for', 'Integer')
16
            }
17
        );
18
        say $out "Added new system preference 'UpdateItemLostStatusWhenPaid'";
19
20
        $dbh->do(
21
            q{
22
                INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type) VALUES ('UpdateItemLostStatusWhenWriteoff', '0', NULL, 'Allows the status of lost items to be automatically changed when item written off', 'Integer')
23
            }
24
        );
25
        say $out "Added new system preference 'UpdateItemLostStatusWhenWriteoff'";
26
    },
27
};
(-)a/installer/data/mysql/mandatory/sysprefs.sql (+2 lines)
Lines 796-801 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
796
('UnsubscribeReflectionDelay','',NULL,'Delay for locking unsubscribers', 'Integer'),
796
('UnsubscribeReflectionDelay','',NULL,'Delay for locking unsubscribers', 'Integer'),
797
('UpdateItemLocationOnCheckin', '', 'NULL', 'This is a list of value pairs.\n Examples:\n\nPROC: FIC - causes an item in the Processing Center location to be updated into the Fiction location on check in.\nFIC: GEN - causes an item in the Fiction location to be updated into the General stacks location on check in.\n_BLANK_:FIC - causes an item that has no location to be updated into the Fiction location on check in.\nFIC: _BLANK_ - causes an item in location FIC to be updated to a blank location on check in.\n_ALL_:FIC - causes all items to be updated into the Fiction location on check in.\nPROC: _PERM_ - causes an item that is in the Processing Center to be updated to it''s permanent location.\n\nGeneral rule: if the location value on the left matches the item''s current location, it will be updated to match the location value on the right.\nNote: PROC and CART are special values, for these locations only can location and permanent_location differ, in all other cases an update will affect both. Items in the CART location will be returned to their permanent location on checkout.\n\nThe special term _BLANK_ may be used on either side of a value pair to update or remove the location from items with no location assigned.\nThe special term _ALL_ is used on the left side of the colon (:) to affect all items.\nThe special term _PERM_ is used on the right side of the colon (:) to return items to their permanent location.', 'Free'),
797
('UpdateItemLocationOnCheckin', '', 'NULL', 'This is a list of value pairs.\n Examples:\n\nPROC: FIC - causes an item in the Processing Center location to be updated into the Fiction location on check in.\nFIC: GEN - causes an item in the Fiction location to be updated into the General stacks location on check in.\n_BLANK_:FIC - causes an item that has no location to be updated into the Fiction location on check in.\nFIC: _BLANK_ - causes an item in location FIC to be updated to a blank location on check in.\n_ALL_:FIC - causes all items to be updated into the Fiction location on check in.\nPROC: _PERM_ - causes an item that is in the Processing Center to be updated to it''s permanent location.\n\nGeneral rule: if the location value on the left matches the item''s current location, it will be updated to match the location value on the right.\nNote: PROC and CART are special values, for these locations only can location and permanent_location differ, in all other cases an update will affect both. Items in the CART location will be returned to their permanent location on checkout.\n\nThe special term _BLANK_ may be used on either side of a value pair to update or remove the location from items with no location assigned.\nThe special term _ALL_ is used on the left side of the colon (:) to affect all items.\nThe special term _PERM_ is used on the right side of the colon (:) to return items to their permanent location.', 'Free'),
798
('UpdateItemLocationOnCheckout', '', 'NULL', 'This is a list of value pairs.\n Examples:\n\nPROC: FIC - causes an item in the Processing Center location to be updated into the Fiction location on check out.\nFIC: GEN - causes an item in the Fiction location to be updated into the General stacks location on check out.\n_BLANK_:FIC - causes an item that has no location to be updated into the Fiction location on check out.\nFIC: _BLANK_ - causes an item in location FIC to be updated to a blank location on check out.\n_ALL_:FIC - causes all items to be updated into the Fiction location on check out.\nPROC: _PERM_ - causes an item that is in the Processing Center to be updated to it''s permanent location.\n\nGeneral rule: if the location value on the left matches the item''s current location, it will be updated to match the location value on the right.\nNote: PROC and CART are special values, for these locations only can location and permanent_location differ, in all other cases an update will affect both. Items in the CART location will be returned to their permanent location on checkout.\n\nThe special term _BLANK_ may be used on either side of a value pair to update or remove the location from items with no location assigned.\nThe special term _ALL_ is used on the left side of the colon (:) to affect all items.\nThe special term _PERM_ is used on the right side of the colon (:) to return items to their permanent location.', 'Free'),
798
('UpdateItemLocationOnCheckout', '', 'NULL', 'This is a list of value pairs.\n Examples:\n\nPROC: FIC - causes an item in the Processing Center location to be updated into the Fiction location on check out.\nFIC: GEN - causes an item in the Fiction location to be updated into the General stacks location on check out.\n_BLANK_:FIC - causes an item that has no location to be updated into the Fiction location on check out.\nFIC: _BLANK_ - causes an item in location FIC to be updated to a blank location on check out.\n_ALL_:FIC - causes all items to be updated into the Fiction location on check out.\nPROC: _PERM_ - causes an item that is in the Processing Center to be updated to it''s permanent location.\n\nGeneral rule: if the location value on the left matches the item''s current location, it will be updated to match the location value on the right.\nNote: PROC and CART are special values, for these locations only can location and permanent_location differ, in all other cases an update will affect both. Items in the CART location will be returned to their permanent location on checkout.\n\nThe special term _BLANK_ may be used on either side of a value pair to update or remove the location from items with no location assigned.\nThe special term _ALL_ is used on the left side of the colon (:) to affect all items.\nThe special term _PERM_ is used on the right side of the colon (:) to return items to their permanent location.', 'Free'),
799
('UpdateItemLostStatusWhenPaid', '0', NULL, 'Allows the status of lost items to be automatically changed to lost and paid for when paid for', 'Integer'),
800
('UpdateItemLostStatusWhenWriteoff', '0', NULL, 'Allows the status of lost items to be automatically changed to lost and paid for when written off', 'Integer'),
799
('UpdateItemWhenLostFromHoldList','',NULL,'This is a list of values to update an item when it is marked as lost from the holds to pull screen','Free'),
801
('UpdateItemWhenLostFromHoldList','',NULL,'This is a list of values to update an item when it is marked as lost from the holds to pull screen','Free'),
800
('UpdateNotForLoanStatusOnCheckin', '', 'NULL', 'This is a list of item types and value pairs.\nExamples:\n_ALL_:\n -1: 0\n\nCR:\n 1: 0\n\nWhen an item is checked in, if its item type matches CR then when the value on the left (1) matches the items not for loan value it will be updated to the value on the right.\n\nThe special term _ALL_ is used on the left side of the colon (:) to affect all item types. This does not override all other rules\n\nEach item type needs to be defined on a separate line on the left side of the colon (:).\nEach pair of not for loan values, for that item type, should be listed on separate lines below the item type, each indented by a leading space.', 'Free'),
802
('UpdateNotForLoanStatusOnCheckin', '', 'NULL', 'This is a list of item types and value pairs.\nExamples:\n_ALL_:\n -1: 0\n\nCR:\n 1: 0\n\nWhen an item is checked in, if its item type matches CR then when the value on the left (1) matches the items not for loan value it will be updated to the value on the right.\n\nThe special term _ALL_ is used on the left side of the colon (:) to affect all item types. This does not override all other rules\n\nEach item type needs to be defined on a separate line on the left side of the colon (:).\nEach pair of not for loan values, for that item type, should be listed on separate lines below the item type, each indented by a leading space.', 'Free'),
801
('UpdateNotForLoanStatusOnCheckout', '', 'NULL', 'This is a list of value pairs. When an item is checked out, if the not for loan value on the left matches the items not for loan value it will be updated to the right-hand value. E.g. ''-1: 0'' will cause an item that was set to ''Ordered'' to now be available for loan. Each pair of values should be on a separate line.', 'Free'),
803
('UpdateNotForLoanStatusOnCheckout', '', 'NULL', 'This is a list of value pairs. When an item is checked out, if the not for loan value on the left matches the items not for loan value it will be updated to the right-hand value. E.g. ''-1: 0'' will cause an item that was set to ''Ordered'' to now be available for loan. Each pair of values should be on a separate line.', 'Free'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref (-1 / +12 lines)
Lines 478-483 Circulation: Link Here
478
                onpayment: "when receiving payment for the item"
478
                onpayment: "when receiving payment for the item"
479
                claim_returned: "when marking an item as a return claim"
479
                claim_returned: "when marking an item as a return claim"
480
            - .
480
            - .
481
        -
482
            - "Update item status to"
483
            - pref: UpdateItemLostStatusWhenPaid
484
              choices: authval
485
              source: LOST
486
            - "when the outstanding balance is paid."
487
        -
488
            - "Update item status to"
489
            - pref: UpdateItemLostStatusWhenWriteoff
490
              choices: authval
491
              source: LOST
492
            - "when the outstanding balance is written off."
481
        -
493
        -
482
            - pref: AllowMultipleIssuesOnABiblio
494
            - pref: AllowMultipleIssuesOnABiblio
483
              choices:
495
              choices:
484
- 

Return to bug 22740