From 31dcca64d50d21f080645cdf21d1ea3efef572db Mon Sep 17 00:00:00 2001 From: Jacob O'Mara Date: Wed, 27 Mar 2024 14:58:13 +0000 Subject: [PATCH] Bug 22740: Automatically change lost status when item is paid for This patch implements two new system preferences, "UpdateItemLostStatusWhenWriteOff" and "UpdateItemLostStatusWhenPaid" that allow you to specify the status to change an item to when the outstanding balance of a lost item is paid or written off. These preferences are tied to the LOST authorised values set. Test Plan: - Set one of the system preference to any of the available values - Set an item as lost - Make a manual invoice for your desired user and assign it to the barcode of the above item - Save and Pay - Select Pay/Write Off depending on the system preference you selected above - Pay - Note that the status of the item has changed to the status you set with the system preference - Repeat for all values of both system preferences - Check that when the system preference is left blank and no option is chosen, the lost status does not update. Signed-off-by: Martin Renvoize Signed-off-by: Laura Escamilla Signed-off-by: Nick Clemens Signed-off-by: Katrin Fischer --- Koha/Account/Line.pm | 121 ++++++++++-------- ...dd_UpdateItemLostStatusWhenPaid_syspref.pl | 27 ++++ installer/data/mysql/mandatory/sysprefs.sql | 2 + .../admin/preferences/circulation.pref | 12 ++ 4 files changed, 106 insertions(+), 56 deletions(-) create mode 100755 installer/data/mysql/atomicupdate/bug_22740-add_UpdateItemLostStatusWhenPaid_syspref.pl diff --git a/Koha/Account/Line.pm b/Koha/Account/Line.pm index 7496f17677..572b16444e 100644 --- a/Koha/Account/Line.pm +++ b/Koha/Account/Line.pm @@ -632,73 +632,82 @@ sub apply { my $schema = Koha::Database->new->schema; - $schema->txn_do( sub { - for my $debit ( @{$debits} ) { + $schema->txn_do( + sub { + for my $debit ( @{$debits} ) { - unless ( $debit->is_debit ) { - Koha::Exceptions::Account::IsNotDebit->throw( - error => 'Account line ' . $debit->id . 'is not a debit' - ); - } - my $amount_to_cancel; - my $owed = $debit->amountoutstanding; + unless ( $debit->is_debit ) { + Koha::Exceptions::Account::IsNotDebit->throw( + error => 'Account line ' . $debit->id . 'is not a debit' ); + } + my $amount_to_cancel; + my $owed = $debit->amountoutstanding; - if ( $available_credit >= $owed ) { - $amount_to_cancel = $owed; - } - else { # $available_credit < $debit->amountoutstanding - $amount_to_cancel = $available_credit; - } + if ( $available_credit >= $owed ) { + $amount_to_cancel = $owed; + } else { # $available_credit < $debit->amountoutstanding + $amount_to_cancel = $available_credit; + } - # record the account offset - Koha::Account::Offset->new( - { credit_id => $self->id, - debit_id => $debit->id, - amount => $amount_to_cancel * -1, - type => 'APPLY' + # record the account offset + Koha::Account::Offset->new( + { + credit_id => $self->id, + debit_id => $debit->id, + amount => $amount_to_cancel * -1, + type => 'APPLY' + } + )->store(); + + $available_credit -= $amount_to_cancel; + + $self->amountoutstanding( $available_credit * -1 )->store; + $debit->amountoutstanding( $owed - $amount_to_cancel )->store; + + # Attempt to renew the item associated with this debit if + # appropriate + if ( $self->credit_type_code ne 'FORGIVEN' && $debit->is_renewable ) { + my $outcome = $debit->renew_item( { interface => $params->{interface} } ); + $self->add_message( + { + type => 'info', + message => 'renewal', + payload => $outcome + } + ) if $outcome; } - )->store(); + $debit->discard_changes; # Refresh values from DB to clear floating point remainders - $available_credit -= $amount_to_cancel; + if ( $debit->debit_type_code + && $debit->debit_type_code eq 'LOST' + && $debit->amountoutstanding == 0 + && $debit->itemnumber + && !( $self->credit_type_code eq 'LOST_FOUND' && $self->itemnumber == $debit->itemnumber ) ) + { - $self->amountoutstanding( $available_credit * -1 )->store; - $debit->amountoutstanding( $owed - $amount_to_cancel )->store; + if ( C4::Context->preference('UpdateItemLostStatusWhenPaid') + && !( $self->credit_type_code eq 'WRITEOFF' || $self->credit_type_code eq 'VOID' ) ) + { + $debit->item->itemlost( C4::Context->preference('UpdateItemLostStatusWhenPaid') )->store(); + } - # Attempt to renew the item associated with this debit if - # appropriate - if ( $self->credit_type_code ne 'FORGIVEN' && $debit->is_renewable ) { - my $outcome = $debit->renew_item( { interface => $params->{interface} } ); - $self->add_message( + if ( C4::Context->preference('UpdateItemLostStatusWhenWriteOff') + && ( $self->credit_type_code eq 'WRITEOFF' || $self->credit_type_code eq 'VOID' ) ) { - type => 'info', - message => 'renewal', - payload => $outcome + $debit->item->itemlost( C4::Context->preference('UpdateItemLostStatusWhenWriteOff') )->store(); } - ) if $outcome; - } - $debit->discard_changes; # Refresh values from DB to clear floating point remainders - - # Same logic exists in Koha::Account::pay - if ( - C4::Context->preference('MarkLostItemsAsReturned') =~ - m|onpayment| - && $debit->debit_type_code - && $debit->debit_type_code eq 'LOST' - && $debit->amountoutstanding == 0 - && $debit->itemnumber - && !( - $self->credit_type_code eq 'LOST_FOUND' - && $self->itemnumber == $debit->itemnumber - ) - ) - { - C4::Circulation::ReturnLostItem( $self->borrowernumber, - $debit->itemnumber ); - } - last if $available_credit == 0; + if ( C4::Context->preference('MarkLostItemsAsReturned') =~ m|onpayment| ) { + C4::Circulation::ReturnLostItem( + $self->borrowernumber, + $debit->itemnumber + ); + } + } + last if $available_credit == 0; + } } - }); + ); Koha::Patron::Debarments::del_restrictions_after_payment( { borrowernumber => $self->borrowernumber } ); diff --git a/installer/data/mysql/atomicupdate/bug_22740-add_UpdateItemLostStatusWhenPaid_syspref.pl b/installer/data/mysql/atomicupdate/bug_22740-add_UpdateItemLostStatusWhenPaid_syspref.pl new file mode 100755 index 0000000000..aaf067157f --- /dev/null +++ b/installer/data/mysql/atomicupdate/bug_22740-add_UpdateItemLostStatusWhenPaid_syspref.pl @@ -0,0 +1,27 @@ +use Modern::Perl; + +return { + bug_number => "22740", + description => + "Preferences to enable automated setting of lost status when the associated fine is paid or written off", + up => sub { + my ($args) = @_; + my ( $dbh, $out ) = @$args{qw(dbh out)}; + + # Do you stuffs here + # sysprefs + $dbh->do( + q{ + 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') + } + ); + say $out "Added new system preference 'UpdateItemLostStatusWhenPaid'"; + + $dbh->do( + q{ + 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') + } + ); + say $out "Added new system preference 'UpdateItemLostStatusWhenWriteoff'"; + }, +}; diff --git a/installer/data/mysql/mandatory/sysprefs.sql b/installer/data/mysql/mandatory/sysprefs.sql index b55473fafa..d1afada379 100644 --- a/installer/data/mysql/mandatory/sysprefs.sql +++ b/installer/data/mysql/mandatory/sysprefs.sql @@ -797,6 +797,8 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` ('UnsubscribeReflectionDelay','',NULL,'Delay for locking unsubscribers', 'Integer'), ('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'), ('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'), +('UpdateItemLostStatusWhenPaid', '0', NULL, 'Allows the status of lost items to be automatically changed to lost and paid for when paid for', 'Integer'), +('UpdateItemLostStatusWhenWriteoff', '0', NULL, 'Allows the status of lost items to be automatically changed to lost and paid for when written off', 'Integer'), ('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'), ('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'), ('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'), diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref index 9370a9b568..0a1bf39d33 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref @@ -478,6 +478,18 @@ Circulation: onpayment: "when receiving payment for the item" claim_returned: "when marking an item as a return claim" - . + - + - "Update item status to" + - pref: UpdateItemLostStatusWhenPaid + choices: authval + source: LOST + - "when the outstanding balance is paid." + - + - "Update item status to" + - pref: UpdateItemLostStatusWhenWriteoff + choices: authval + source: LOST + - "when the outstanding balance is written off." - - pref: AllowMultipleIssuesOnABiblio choices: -- 2.39.5