diff --git a/app/models/distribution.rb b/app/models/distribution.rb index 08b6fdbb29..cf7561fe5c 100644 --- a/app/models/distribution.rb +++ b/app/models/distribution.rb @@ -46,6 +46,9 @@ class Distribution < ApplicationRecord enum state: { scheduled: 5, complete: 10 } enum delivery_method: { pick_up: 0, delivery: 1, shipped: 2 } + scope :active, -> { joins(:line_items).joins(:items).where(items: { active: true }) } + scope :with_diapers, -> { joins(line_items: :item).merge(Item.disposable.or(Item.cloth_diapers)) } + scope :with_period_supplies, -> { joins(line_items: :item).merge(Item.period_supplies) } # add item_id scope to allow filtering distributions by item scope :by_item_id, ->(item_id) { includes(:items).where(items: { id: item_id }) } # partner scope to allow filtering by partner @@ -70,6 +73,10 @@ class Distribution < ApplicationRecord where("issued_at > :start_date AND issued_at <= :end_date", start_date: Time.zone.today.beginning_of_week.beginning_of_day, end_date: Time.zone.today.end_of_week.end_of_day) end + scope :in_last_12_months, -> do + where("issued_at > :start_date AND issued_at <= :end_date", + start_date: 12.months.ago.beginning_of_day, end_date: Time.zone.today.end_of_day) + end delegate :name, to: :partner, prefix: true diff --git a/app/models/partner.rb b/app/models/partner.rb index 52029a444a..d8be7e4b61 100644 --- a/app/models/partner.rb +++ b/app/models/partner.rb @@ -186,7 +186,9 @@ def self.csv_export_headers "Contact Phone", "Contact Email", "Notes", - "Counties Served" + "Counties Served", + "Providing Diapers", + "Providing Period Supplies" ] end @@ -204,10 +206,20 @@ def csv_export_attributes contact_person[:phone], contact_person[:email], notes, - profile.county_list_by_region + profile.county_list_by_region, + providing_diapers, + providing_period_supplies ] end + def providing_diapers + distributions.in_last_12_months.with_diapers.any? ? "Y" : "N" + end + + def providing_period_supplies + distributions.in_last_12_months.with_period_supplies.any? ? "Y" : "N" + end + def contact_person return @contact_person if @contact_person diff --git a/spec/models/distribution_spec.rb b/spec/models/distribution_spec.rb index b03c485e16..faa8e804d4 100644 --- a/spec/models/distribution_spec.rb +++ b/spec/models/distribution_spec.rb @@ -139,6 +139,34 @@ end end + describe "in_last_12_months >" do + context "when the current date is December 31, 2023" do + before do + travel_to Time.zone.local(2023, 12, 31) + end + + after do + travel_back + end + + it "includes distributions issued within the last 12 months" do + included_distribution = create(:distribution, organization: organization, issued_at: Time.zone.local(2023, 1, 1)) + excluded_distribution = create(:distribution, organization: organization, issued_at: Time.zone.local(2022, 12, 30)) + distributions = Distribution.in_last_12_months + expect(distributions).to include(included_distribution) + expect(distributions).not_to include(excluded_distribution) + end + + it "includes distributions up to the current date and excludes future ones" do + current_distribution = create(:distribution, organization: organization, issued_at: Time.zone.local(2023, 12, 31)) + future_distribution = create(:distribution, organization: organization, issued_at: Time.zone.local(2024, 1, 1)) + distributions = Distribution.in_last_12_months + expect(distributions).to include(current_distribution) + expect(distributions).not_to include(future_distribution) + end + end + end + describe "by_item_id >" do it "only returns distributions with given item id" do # create 2 items with unique ids @@ -176,6 +204,39 @@ expect(Distribution.by_location(location_1.id)).not_to include(dist2) end end + + describe "with_diapers >" do + let(:disposable_item) { create(:item, base_item: create(:base_item, category: "Diapers - Childrens")) } + let(:cloth_diaper_item) { create(:item, base_item: create(:base_item, category: "Diapers - Cloth (Kids)")) } + let(:non_diaper_item) { create(:item, base_item: create(:base_item, category: "Menstrual Supplies/Items")) } + + it "only includes distributions with disposable or cloth_diaper items" do + dist1 = create(:distribution, :with_items, item: disposable_item) + dist2 = create(:distribution, :with_items, item: cloth_diaper_item) + dist3 = create(:distribution, :with_items, item: non_diaper_item) + + distributions = Distribution.with_diapers + expect(distributions.count).to eq(2) + expect(distributions).to include(dist1) + expect(distributions).to include(dist2) + expect(distributions).not_to include(dist3) + end + end + + describe "with_period_supplies >" do + let(:period_supplies_item) { create(:item, base_item: create(:base_item, category: "Menstrual Supplies/Items")) } + let(:non_period_supplies_item) { create(:item, base_item: create(:base_item, category: "Diapers - Childrens")) } + + it "only includes distributions with period supplies items" do + dist1 = create(:distribution, :with_items, item: period_supplies_item) + dist2 = create(:distribution, :with_items, item: non_period_supplies_item) + + distributions = Distribution.with_period_supplies + expect(distributions.count).to eq(1) + expect(distributions).to include(dist1) + expect(distributions).not_to include(dist2) + end + end end context "Callbacks >" do diff --git a/spec/models/partner_spec.rb b/spec/models/partner_spec.rb index 5364f872d3..a3e0a06060 100644 --- a/spec/models/partner_spec.rb +++ b/spec/models/partner_spec.rb @@ -299,6 +299,8 @@ let(:agency_type) { Partner::AGENCY_TYPES["OTHER"] } let(:other_agency_type) { "Another Agency Name" } let(:notes) { "Some notes" } + let(:providing_diapers) { {value: "N", index: 13} } + let(:providing_period_supplies) { {value: "N", index: 14} } before do partner.profile.update({ @@ -340,9 +342,76 @@ contact_phone, contact_email, notes, - correctly_ordered_counties + correctly_ordered_counties, + providing_diapers[:value], + providing_period_supplies[:value] ]) end + + context "when partner has a distribution in the last 12 months" do + let(:distribution) { create(:distribution, partner: partner) } + + shared_examples "providing_diapers check" do |scope| + before do + providing_diapers[:value] = "Y" + + case scope + when :disposable + item = create(:item, base_item: create(:base_item, category: "Diapers - Childrens")) + when :cloth_diapers + item = create(:item, base_item: create(:base_item, category: "Diapers - Cloth (Kids)")) + end + + create(:line_item, item: item, itemizable: distribution) + end + + it "should have Y as providing_diapers" do + expect(partner.csv_export_attributes[providing_diapers[:index]]).to eq(providing_diapers[:value]) + end + end + + context "with a disposable item" do + include_examples "providing_diapers check", :disposable + end + + context "with a cloth diaper item" do + include_examples "providing_diapers check", :cloth_diapers + end + + context "with a period supplies item" do + before do + providing_period_supplies[:value] = "Y" + + item = create(:item, base_item: create(:base_item, category: "Menstrual Supplies/Items")) + create(:line_item, item: item, itemizable: distribution) + end + + it "should have Y as providing_period_supplies" do + expect(partner.csv_export_attributes[providing_period_supplies[:index]]).to eq(providing_period_supplies[:value]) + end + end + end + + context "when partner only has distribution older than a 12 months" do + let(:distribution) { create(:distribution, issued_at: (12.months.ago.beginning_of_day - 1.day), partner: partner) } + let(:disposable_diapers_item) { create(:item, base_item: create(:base_item, category: "Diapers - Childrens")) } + let(:cloth_diapers_item) { create(:item, base_item: create(:base_item, category: "Diapers - Cloth (Kids)")) } + let(:period_supplies_item) { create(:item, base_item: create(:base_item, category: "Menstrual Supplies/Items")) } + + before do + create(:line_item, item: disposable_diapers_item, itemizable: distribution) + create(:line_item, item: cloth_diapers_item, itemizable: distribution) + create(:line_item, item: period_supplies_item, itemizable: distribution) + end + + it "should have N as providing_diapers" do + expect(partner.csv_export_attributes[providing_diapers[:index]]).to eq(providing_diapers[:value]) + end + + it "should have N as providing_period_supplies" do + expect(partner.csv_export_attributes[providing_period_supplies[:index]]).to eq(providing_period_supplies[:value]) + end + end end describe '#quantity_year_to_date' do