CIRC-1778: actual cost fees expiring prematurely
This page contains information about a bug in mod-circulation introduced in CIRC-1566 (released in Nolana) and fixed in CIRC-1778 (release planned for Poppy).
ACR = actual cost record
Context
"Actual cost record" (ACR) is a back-end term used for automated lost item fees found on this page (Users → Actions → Lost items requiring actual cost):
An ACR can be thought of as a template for a "real" lost item fee which does not have the amount yet. The amount needs to be specified manually by the user. Once it is done, the ACR's status is changed from Open to Billed, and a "real" lost item fee is created with the specified amount.
Actual cost fees are enabled via Lost Item Fee Policy by selecting Actual cost in section Charge amount for item:
When such a fee is created using a Lost Item Fee Policy which has setting "For lost items not charged a fee/fine, close the loan after..." enabled, the fee will be created with an additional property expirationDate. The value of this property is equal to the value of property lossDate plus the period specified in the aforementioned setting.
There is a background job running in mod-circulation that scans the all ACRs every 20 minutes in search of open records with past expiration date. Once an expired ACR is found, its status is changed from Open to Expired, and the lost item fee is never billed.
Impact
Because of CIRC-1778, even ACR created using a Lost Item Fee Policy which DOES NOT have setting "For lost items not charged a fee/fine, close the loan after..." enabled would also have an expirationDate, with its value equal to lossDate. Such ACR would expire soon after the item is lost, while according to Lost Item Fee Policy it should not have had an expiration date in the first place.
Because of another bug in mod-circulation (CIRC-1866, fix also planned for Poppy), when expired ACR is processed, the corresponding loan is not closed as (in cases when it is supposed to). So loans are not affected by CIRC-1778. The impact is limited to ACRs only.
Workaround
If your library is affected OR is planning to start using actual cost fees, please enable setting "For lost items not charged a fee/fine, close the loan after..." in every Lost Item Fee Policy where actual cost is enabled. This will prevent creation of corrupted actual cost records. If you don't want your ACRs to actually expire anytime soon, you can use an unreasonably large time period for this setting. This workaround can be safely reverted once the fix for CIRC-1778 is deployed to your environment.
Q&A
1) How do I know if my library is affected?
Replace {TENANT_ID} with your tenant ID and run the following query:
SELECT COUNT(*) from {TENANT_ID}_mod_circulation_storage.actual_cost_record WHERE jsonb->'expirationDate' IS NOT NULL AND jsonb->'expirationDate' = jsonb->'lossDate';
If it returns a number greater than zero, your library is affected.
2) How do I fix affected ACRs?
Replace {TENANT_ID} with your tenant ID and run the following query:
UPDATE {TENANT_ID}_mod_circulation_storage.actual_cost_record SET jsonb = jsonb_set(jsonb, '{status}', '"Open"') - 'expirationDate' WHERE jsonb->>'status' = 'Expired' AND jsonb->'expirationDate' IS NOT NULL AND jsonb->'expirationDate' = jsonb->'lossDate';
This query will remove expiration date from affected ACRs (as they should not have had it anyway) and change their status back from Expired to Open. We are planning to run this script automatically as a part of upgrade to Poppy.