-
-
Notifications
You must be signed in to change notification settings - Fork 498
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
3611: Refactor of storage location inventory updates #3614
Conversation
We don't allow updates of adjustments. so they're definitely not a problem. I'm not sure I follow, yet, how audits and transfers aren't an issue. |
@@ -129,6 +129,10 @@ def self.import_inventory(filename, org, loc) | |||
adjustment.storage_location.increase_inventory(adjustment) | |||
end | |||
|
|||
def remove_empty_items | |||
inventory_items.where(quantity: 0).delete_all |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Beware, delete_all skips callbacks. Is that ok here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep. Confirmed inventory items has no callbacks.
increase_method = (type == :increase) ? :increase_inventory : :decrease_inventory | ||
decrease_method = (type == :increase) ? :decrease_inventory : :increase_inventory |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the names flip around depending on the direction, how about we change to a name that describes the intent a bit better. Here's an idea:
increase_method = (type == :increase) ? :increase_inventory : :decrease_inventory | |
decrease_method = (type == :increase) ? :decrease_inventory : :increase_inventory | |
apply_change_method = (type == :increase) ? :increase_inventory : :decrease_inventory | |
undo_change_method = (type == :increase) ? :decrease_inventory : :increase_inventory |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Love it!
update_storage_location(itemizable: itemizable, | ||
increase_method: increase_method, | ||
decrease_method: decrease_method, | ||
params: params, | ||
from_location: from_location, | ||
to_location: to_location) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So here is what that rename would be here:
update_storage_location(itemizable: itemizable, | |
increase_method: increase_method, | |
decrease_method: decrease_method, | |
params: params, | |
from_location: from_location, | |
to_location: to_location) | |
update_storage_location(itemizable: itemizable, | |
apply_change_method: apply_change_method, | |
undo_change_method: undo_change_method, | |
params: params, | |
from_location: from_location, | |
to_location: to_location) |
# @param itemizable [Itemizable] | ||
# @param increase_method [Symbol] | ||
# @param decrease_method [Symbol] | ||
# @param params [Hash] Parameters passed from the controller. Should include `line_item_attributes`. | ||
# @param from_location [StorageLocation] | ||
# @param to_location [StorageLocation] | ||
def self.update_storage_location(itemizable:, increase_method:, decrease_method:, | ||
params:, from_location:, to_location:) | ||
from_location.public_send(decrease_method, itemizable.to_a) | ||
# Delete the line items -- they'll be replaced later | ||
itemizable.line_items.delete_all | ||
# Update the current model with the new parameters | ||
itemizable.update!(params) | ||
itemizable.reload | ||
# Apply the new changes to the storage location inventory | ||
to_location.public_send(increase_method, itemizable.to_a) | ||
|
||
from_location.remove_empty_items | ||
to_location.remove_empty_items | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And here
# @param itemizable [Itemizable] | |
# @param increase_method [Symbol] | |
# @param decrease_method [Symbol] | |
# @param params [Hash] Parameters passed from the controller. Should include `line_item_attributes`. | |
# @param from_location [StorageLocation] | |
# @param to_location [StorageLocation] | |
def self.update_storage_location(itemizable:, increase_method:, decrease_method:, | |
params:, from_location:, to_location:) | |
from_location.public_send(decrease_method, itemizable.to_a) | |
# Delete the line items -- they'll be replaced later | |
itemizable.line_items.delete_all | |
# Update the current model with the new parameters | |
itemizable.update!(params) | |
itemizable.reload | |
# Apply the new changes to the storage location inventory | |
to_location.public_send(increase_method, itemizable.to_a) | |
from_location.remove_empty_items | |
to_location.remove_empty_items | |
end | |
end | |
# @param itemizable [Itemizable] | |
# @param apply_change_method [Symbol] | |
# @param undo_change_method [Symbol] | |
# @param params [Hash] Parameters passed from the controller. Should include `line_item_attributes`. | |
# @param from_location [StorageLocation] | |
# @param to_location [StorageLocation] | |
def self.update_storage_location(itemizable:, apply_change_method:, undo_change_method:, | |
params:, from_location:, to_location:) | |
from_location.public_send(undo_change_method, itemizable.to_a) | |
# Delete the line items -- they'll be replaced later | |
itemizable.line_items.delete_all | |
# Update the current model with the new parameters | |
itemizable.update!(params) | |
itemizable.reload | |
# Apply the new changes to the storage location inventory | |
to_location.public_send(apply_change_method, itemizable.to_a) | |
from_location.remove_empty_items | |
to_location.remove_empty_items | |
end | |
end |
I note that decrease will throw |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider the method swappy swap rename.
I think we have an outstanding issue around catching that appropriately |
spec/factories/storage_locations.rb
Outdated
item_quantity { 100 } | ||
item { nil } | ||
end | ||
|
||
after(:create) do |storage_location, evaluator| | ||
if evaluator.item.nil? | ||
if evaluator.item.nil? && evaluator.item_count != 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if evaluator.item.nil? && evaluator.item_count != 0 | |
if evaluator.item.nil? && !evaluator.item_count.zero? |
Just some syntactic sugar
@awwaiid thanks for the suggestions - added in the fixes! Please check again. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great! (some minor lint remains)
Fixed! |
Any reason we haven't merged this yet? |
Don't think so! Let's go for it. |
Resolves #3611
Description
This refactors the updating of storage location inventory to move it to a single place that works for distributions, purchases and donations. The centralized place uses the fix discovered in #3601 to address the race condition we found with distributions.
(Note - there are also adjustments, audits and transfers that affect inventory, but these do not make any changes to the line items themselves - in these cases the line items represent the transfer between locations rather than an update to an event that represents an increase or decrease in inventory.)
Type of change
Internal change
How Has This Been Tested?
Local and unit tests.