diff --git a/app/models/item.rb b/app/models/item.rb index 7142b98b97..59cbff01f8 100644 --- a/app/models/item.rb +++ b/app/models/item.rb @@ -47,7 +47,7 @@ class Item < ApplicationRecord validate :has_no_line_items, if: -> { kit.blank? } - has_many :line_items, dependent: :destroy + has_many :contained_in_line_items, class_name: "LineItem", dependent: :destroy has_many :inventory_items, dependent: :destroy has_many :barcode_items, as: :barcodeable, dependent: :destroy has_many :storage_locations, through: :inventory_items diff --git a/app/models/organization.rb b/app/models/organization.rb index d8f46221a6..3364444751 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -83,18 +83,20 @@ def other def during(date_start, date_end = Time.zone.now.strftime("%Y-%m-%d")) select("COUNT(line_items.id) as amount, name") - .joins(:line_items) - .where("line_items.created_at BETWEEN ? and ?", date_start, date_end) - .group(:name) + .joins(:contained_in_line_items) + .merge(LineItem.where(created_at: date_start..date_end)) + .group(:name) end def top(limit = 5) order('count(line_items.id) DESC') + .joins(:contained_in_line_items) .limit(limit) end def bottom(limit = 5) order('count(line_items.id) ASC') + .joins(:contained_in_line_items) .limit(limit) end end diff --git a/app/services/historical_trend_service.rb b/app/services/historical_trend_service.rb index f8615a625b..c6aeb306b5 100644 --- a/app/services/historical_trend_service.rb +++ b/app/services/historical_trend_service.rb @@ -7,7 +7,7 @@ def initialize(organization_id, type) def series # Preload line_items with a single query to avoid N+1 queries. items_with_line_items = @organization.items.active - .includes(:line_items) + .includes(:contained_in_line_items) .where(line_items: {itemizable_type: @type, created_at: 1.year.ago.beginning_of_month..Time.current}) .order(:name) @@ -17,7 +17,7 @@ def series items_with_line_items.each_with_object([]) do |item, array_of_items| dates = default_dates.deep_dup - item.line_items.each do |line_item| + item.contained_in_line_items.each do |line_item| month = line_item.created_at.month index = month_offset.index(month) + 1 dates[index] = dates[index] + line_item.quantity diff --git a/spec/models/item_spec.rb b/spec/models/item_spec.rb index 433eaa893e..f53a3458d8 100644 --- a/spec/models/item_spec.rb +++ b/spec/models/item_spec.rb @@ -26,8 +26,13 @@ let(:organization) { create(:organization) } - describe 'Assocations >' do + describe 'Associations >' do it { should belong_to(:item_category).optional } + it "should return line items containing the item" do + item = create(:item) + create(:line_item, item: item) + expect(item.contained_in_line_items.count).to eq(1) + end end context "Validations >" do it "requires a unique name" do @@ -44,8 +49,10 @@ it { should validate_numericality_of(:on_hand_recommended_quantity).is_greater_than_or_equal_to(0) } context "Doesn't house a kit >" do - it "ensures associated line_items are empty" do + it "ensures associated itemizable line_items don't exist without invalidating associated line_items" do item = create(:item) + create(:line_item, item: item) + expect(item).to be_valid item.line_items << build(:line_item, quantity: 1) expect(item).not_to be_valid end