Enforce loan preparation availability on insert (fixes #8188)#8189
Enforce loan preparation availability on insert (fixes #8188)#8189foozleface wants to merge 2 commits into
Conversation
The #7665 fix added an early return that skipped the loanprep_quantity_must_be_lte_availability rule whenever the row was new, disabling server-side over-loan protection on every creation path (Add Unassociated Item, REST API, WorkBench uploads). Remove the early return so the rule validates inserts again, matching the gift and exchangeout sibling rules. The null-safe int(x or 0) handling that actually fixed #7665 is unchanged.
A loanpreparation row with a NULL quantityresolved (e.g. created by a WorkBench upload with Quantity Resolved unmapped) made the whole quantity-quantityresolved term NULL, so the row contributed nothing to the amount on loan and availability was overstated. Coalesce both fields to 0, matching the int(x or 0) handling on the Python side.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThis PR fixes a regression in loan preparation availability validation. The rule was inadvertently disabled for new records by an earlier NULL-safety fix. The change restores enforcement at insert time by making the quantity calculation fully NULL-safe and removing a conditional that skipped validation for unsaved objects. Comprehensive tests verify the behavior across insert, update, and resolved scenarios. ChangesLoan Preparation Availability Validation
🚥 Pre-merge checks | ✅ 5 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Fixes #8188
The fix for #7665 (79c3a4f) added an early return to
loanprep_quantity_must_be_lte_availabilitythat skips the rule wheneveripreparation.id is None— i.e. on every INSERT. Since then the server has not enforced preparation availability when a loan preparation is created, so a specimen can be placed on two open loans at once through any path that bypasses the frontend InteractionDialog pre-query ("Add Unassociated Item", direct REST API POSTs, WorkBench loan uploads). The gift and exchange-out rules in the same file validate on insert; loans were the only interaction that did not.This PR removes the early return so the availability check runs on insert again, matching the sibling rules. The null-safe quantity handling from the #7665 fix (
int(x or 0)) is kept — that alone fixes #7665, which was aTypeErrorfrom callingint(None)when Quantity Resolved was unmapped in a WorkBench upload. On insert,get_availabilityis called withiprepid=Noneand correctly skips the self-exclusion clause, so no other change is needed.A second commit fixes the matching null-safety gap in
get_availability's SQL:sum(lp.quantity - lp.quantityresolved)goes NULL for a row whosequantityresolvedis NULL (e.g. created by a WorkBench upload with Quantity Resolved unmapped), so that row contributed nothing to the on-loan amount and availability was overstated. Both fields are now coalesced to 0, matching the Python side.Added
specifyweb/backend/businessrules/tests/test_loanpreparation.pycovering:BusinessRuleException(the regression)quantityresolveddoes not crash the rule ("Quantity Resolved" incorrectly enforced as required in WorkBench #7665 regression guard) and still counts as fully unresolvedAll existing loan-preparation-creating tests in
businessrules,interactions,specify, andworkbenchstay within availability, so no other test changes were needed.Summary by CodeRabbit