-
-
Notifications
You must be signed in to change notification settings - Fork 447
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
4052 disallow deleting transfers if audit #4057
4052 disallow deleting transfers if audit #4057
Conversation
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.
Thanks for the contribution! I had some suggestions.
app/models/transfer.rb
Outdated
@@ -56,6 +56,11 @@ def csv_export_attributes | |||
] | |||
end | |||
|
|||
def deletable? | |||
item_ids = line_items.pluck(:item_id) | |||
Audit.where(storage_location_id: [to_id, from_id]).where(created_at: created_at..).joins(:line_items).where(line_items: {item_id: item_ids}).empty? |
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.
Can we split this line up to make it more readable?
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.
Also, I'm not sure this belongs inside Transfer
since it really isn't checking transfers at all. I think it'd make more sense to move this to the Audit
class as a method, e.g. Audit.since?(self)
and it can take an Itemizable
as its parameter.
@@ -4,6 +4,8 @@ def initialize(transfer_id:) | |||
end | |||
|
|||
def call | |||
raise StandardError.new "Transfer cannot be deleted" unless transfer.deletable? |
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.
You don't need to explicitly call out StandardError
:
raise "Transfer cannot be deleted" unless transfer.deletable?
But can you add more information here? "Transfer cannot be deleted since an audit was performed after it."
spec/system/transfer_system_spec.rb
Outdated
@@ -135,5 +135,21 @@ def create_transfer(amount, from_name, to_name) | |||
end | |||
|
|||
it_behaves_like "Date Range Picker", Transfer | |||
|
|||
it "only displays delete button for deletable transfers" do |
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 this doesn't have any interaction, it can be a request spec (which uses a lot less resources).
I'll get to work on the changes. One question @dorner, how do you feel about splitting up the query in Audit like:
And then transfer's deletable method could be:
Since I believe only transfers have both a |
I don't think we need to split it up since we only have one use case. But you can pass in a list of location IDs as an array. |
…er test, add test for audit query method
@@ -4,6 +4,8 @@ def initialize(transfer_id:) | |||
end | |||
|
|||
def call | |||
raise "Transfer cannot be deleted because an audit was performed after it" unless transfer.deletable? |
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.
Hmm... I'm torn here because the name of the method is generic ("can this be deleted") but the error assumes there is only one possible reason the audit couldn't be deleted. I think it's OK to just have this service call Audit.since?
directly rather than deletable?
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.
You mean that the transfer couldn't be deleted, yes?
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.
@dorner Originally, I was thinking that a delete button would only appear if the transfer met the criteria for deletability and that the view might look cleaner with a deletable?
method, but since that's not the case there doesn't seem to be a reason for it.
@@ -5,7 +5,9 @@ | |||
<td><%= transfer_row.comment || "none" %></td> | |||
<td><%= transfer_row.line_items.total %></td> | |||
<td> | |||
<%= delete_button_to transfer_path(transfer_row.id), { confirm: "Are you sure you want to permanently remove this transfer?" } %> | |||
<% if transfer_row.deletable? %> |
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.
In general we don't do validations before we perform the action. @cielf would it be OK to only have this raise an error and not try to change the view beforehand? I think this is an edge case and I don't want to overthink this.
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.
It's definitely an edge case. I'm ok with that -- we need to be pretty clear on why they can't in the error, though.
@@ -5,7 +5,9 @@ | |||
<td><%= transfer_row.comment || "none" %></td> | |||
<td><%= transfer_row.line_items.total %></td> | |||
<td> | |||
<%= delete_button_to transfer_path(transfer_row.id), { confirm: "Are you sure you want to permanently remove this transfer?" } %> | |||
<% if transfer_row.deletable? %> |
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.
In general we don't do validations before we perform the action. @cielf would it be OK to only have this raise an error and not try to change the view beforehand? I think this is an edge case and I don't want to overthink this.
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.
It's definitely an edge case. I'm ok with that -- we need to be pretty clear on why they can't in the error, though.
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.
@cielf Is "Transfer cannot be deleted because an audit was performed after it" a clear enough message? Or maybe something more specific like "This transfer cannot be deleted because an audit involving its items has already been performed"? I can't tell if being more specific makes the error message clearer.
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.
@MooseCowBear I don't want to spend too much time on the wording because this is a bit of an edge case. How about "We can't delete this transfer because its items were audited since you made the transfer."
Looks good - thanks! |
@MooseCowBear: Your PR |
Resolves #4052
Description
This PR adds a method
deletable?
to the Transfer model to check if any audits have occurred 1. since the transfer was created at either the transfer'sto
location or itsfrom
location, and 2. that the audit involved items that were transferred. It updates the transfer_row partial to only display a delete button if there are no such audits.It also adds a check that the transfer is deletable in the DestroyTransferService so that the controller wouldn't destroy a transfer that shouldn't be deleted. (If you decide you don't want this, I'm happy to remove it.)
The query for audits is kind of beastly. I couldn't think of a better way that would keep the db queries to a minimum.
Type of change
How Has This Been Tested?
I added unit tests for correctness of the method and the change to the service, and a system test for the conditional delete button rendering.
Screenshots