@@ -94,6 +94,8 @@ class Item < ApplicationRecord
9494 . or ( where ( "base_items.category = 'Miscellaneous'" ) )
9595 }
9696
97+ before_destroy :validate_destroy , prepend : true
98+
9799 def self . barcoded_items
98100 joins ( :barcode_items ) . order ( :name ) . group ( :id )
99101 end
@@ -111,20 +113,49 @@ def self.reactivate(item_ids)
111113 Item . where ( id : item_ids ) . find_each { |item | item . update ( active : true ) }
112114 end
113115
116+ def has_inventory? ( inventory = nil )
117+ if inventory
118+ inventory . quantity_for ( item_id : id ) . positive?
119+ else
120+ inventory_items . where ( "quantity > 0" ) . any?
121+ end
122+ end
123+
124+ def is_in_kit?
125+ organization . kits
126+ . active
127+ . joins ( :line_items )
128+ . where ( line_items : { item_id : id } ) . any?
129+ end
130+
131+ def can_delete? ( inventory = nil )
132+ can_deactivate_or_delete? ( inventory ) && line_items . none? && !barcode_count &.positive?
133+ end
134+
114135 # @return [Boolean]
115- def can_deactivate?
136+ def can_deactivate_or_delete? ( inventory = nil )
137+ if inventory . nil? && Event . read_events? ( organization )
138+ inventory = View ::Inventory . new ( organization_id )
139+ end
116140 # Cannot deactivate if it's currently in inventory in a storage location. It doesn't make sense
117141 # to have physical inventory of something we're now saying isn't valid.
118- inventory_items . where ( "quantity > 0" ) . none? &&
119- # If an active kit includes this item, then changing kit allocations would change inventory
120- # for an inactive item - which we said above we don't want to allow.
121- organization . kits
122- . active
123- . joins ( :line_items )
124- . where ( line_items : { item_id : id } ) . none?
142+ # If an active kit includes this item, then changing kit allocations would change inventory
143+ # for an inactive item - which we said above we don't want to allow.
144+
145+ !has_inventory? ( inventory ) && !is_in_kit?
146+ end
147+
148+ def validate_destroy
149+ unless can_delete?
150+ errors . add ( :base , "Cannot delete item - it has already been used!" )
151+ throw ( :abort )
152+ end
125153 end
126154
127- def deactivate
155+ def deactivate!
156+ unless can_deactivate_or_delete?
157+ raise "Cannot deactivate item - it is in a storage location or kit!"
158+ end
128159 if kit
129160 kit . deactivate
130161 else
@@ -136,27 +167,6 @@ def other?
136167 partner_key == "other"
137168 end
138169
139- # Override `destroy` to ensure Item isn't accidentally destroyed
140- # without first being disassociated with its historical presence
141- def destroy
142- if has_history?
143- deactivate
144- else
145- super
146- end
147- end
148-
149- def has_history?
150- return true if line_items . any? || barcode_items . any?
151-
152- if Event . read_events? ( organization )
153- inventory = View ::Inventory . new ( organization_id )
154- inventory . quantity_for ( item_id : id ) . positive?
155- else
156- inventory_items . any?
157- end
158- end
159-
160170 def self . gather_items ( current_organization , global = false )
161171 if global
162172 where ( id : current_organization . barcode_items . all . pluck ( :barcodeable_id ) )
0 commit comments