Skip to content
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

4513 incontinence supplies #4794

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
1d93dcd
Begin working calculations for new feild addtions for report and upda…
jadekstewart3 Oct 29, 2024
7ec4f2d
Created kits in spec to ensure report values update with kit creation…
jadekstewart3 Nov 20, 2024
607bec6
Update total_people_served_with_supplies_from_kits_per_month as descr…
jadekstewart3 Nov 27, 2024
ffa5b51
Remove commented text
jadekstewart3 Nov 27, 2024
fb68000
Modify calculation for adults served to ensure accurate values
jadekstewart3 Dec 11, 2024
28aa472
Evaluate how monthly supplies is calculated and modify to produce mor…
jadekstewart3 Dec 11, 2024
062d5a6
Merge branch 'main' of github.com:jadekstewart3/human-essentials into…
jadekstewart3 Dec 12, 2024
203730e
Update spec to passing, still working on identifying where service is…
jadekstewart3 Dec 12, 2024
a8816a0
rubocop
jadekstewart3 Dec 12, 2024
ac49fe5
Modify total_people_served_with_supplies_from_kits_per_month and tota…
jadekstewart3 Dec 16, 2024
fca526d
Modify kit item test set up, and add kits to endure calculations are …
jadekstewart3 Dec 16, 2024
a3b1155
Re-work kit test set up
jadekstewart3 Dec 16, 2024
ac542f8
Remove trailing whitespace
jadekstewart3 Dec 16, 2024
8a61604
rubocop
jadekstewart3 Dec 16, 2024
a0270f9
Fix oversight in distributed_adult_incontinence_items_from_kits, and …
jadekstewart3 Dec 19, 2024
c2f90ad
Modify how we calculate total_people_served_with_supplies_from_kits_p…
jadekstewart3 Dec 20, 2024
1fac9db
rubocop
jadekstewart3 Dec 20, 2024
b55672e
Create additional test to confirm functionality of distributed_adult_…
jadekstewart3 Jan 2, 2025
e2c41a6
Fixed test set up including kit containing wipes, correct amount of d…
jadekstewart3 Jan 2, 2025
15c7c84
Fix spacing per rubocop
jadekstewart3 Jan 2, 2025
91b7f16
Adjust methods to calculate monthly values, and correct test expectat…
jadekstewart3 Jan 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 54 additions & 3 deletions app/services/reports/adult_incontinence_report_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ def initialize(year:, organization:)
def report
@report ||= { name: 'Adult Incontinence',
entries: {
'Adult incontinence supplies distributed' => number_with_delimiter(distributed_supplies),
'Adult incontinence supplies per adult per month' => monthly_supplies&.round || 0,
'Adult incontinence supplies distributed' => number_with_delimiter(distributed_loose_supplies + distributed_adult_incontinence_items_from_kits),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this not total_supplies_distributed?

'Adults Assisted Per Month' => adults_served_per_month.round,
'Adult incontinence supplies per adult per month' => (monthly_supplies&.round || 0) / (adults_served_per_month.round.nonzero? || 1),
'Adult incontinence supplies' => types_of_supplies,
'% adult incontinence supplies donated' => "#{percent_donated.round}%",
'% adult incontinence bought' => "#{percent_bought.round}%",
Expand All @@ -24,7 +25,7 @@ def report
end

# @return [Integer]
def distributed_supplies
def distributed_loose_supplies
@distributed_supplies ||= organization
.distributions
.for_year(year)
Expand All @@ -47,6 +48,7 @@ def monthly_supplies
end

def types_of_supplies
# require 'pry'; binding.pry
organization.items.adult_incontinence.map(&:name).uniq.sort.join(', ')
end

Expand Down Expand Up @@ -91,5 +93,54 @@ def donated_supplies
.where(itemizable: organization.donations.for_year(year))
.sum(:quantity)
end

def distributed_adult_incontinence_items_from_kits
organization_id = @organization.id
year = @year

sql_query = <<-SQL
SELECT SUM(line_items.quantity * kit_line_items.quantity)
FROM distributions
INNER JOIN line_items ON line_items.itemizable_type = 'Distribution' AND line_items.itemizable_id = distributions.id
INNER JOIN items ON items.id = line_items.item_id
INNER JOIN kits ON kits.id = items.kit_id
INNER JOIN line_items AS kit_line_items ON kits.id = kit_line_items.itemizable_id
INNER JOIN items AS kit_items ON kit_items.id = kit_line_items.item_id
INNER JOIN base_items ON base_items.partner_key = kit_items.partner_key
WHERE distributions.organization_id = ?
AND EXTRACT(year FROM issued_at) = ?
AND LOWER(base_items.category) LIKE '%adult%'
AND NOT (LOWER(base_items.category) LIKE '%cloth%' OR LOWER(base_items.name) LIKE '%cloth%')
AND kit_line_items.itemizable_type = 'Kit';
SQL
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be excluding cloth (Adult Cloth Diapers count as AI) and should be excluding wipes. See Item.adult_incontinence.


sanitized_sql = ActiveRecord::Base.send(:sanitize_sql_array, [sql_query, organization_id, year])

result = ActiveRecord::Base.connection.execute(sanitized_sql)

result.first['sum'].to_i
end

def adults_served_per_month
total_people_served_with_loose_supplies_per_month + total_people_served_with_supplies_from_kits_per_month
end

def total_people_served_with_loose_supplies_per_month
organization
.distributions
.for_year(year)
.joins(line_items: :item)
.merge(Item.adult_incontinence)
.sum('line_items.quantity / COALESCE(items.distribution_quantity, 50)') / 12
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is giving you an integer for each item/distribution combo - I found that it was significantly undercounting with our seed data. Changing 50 to 50.0 gave me the value I expected in my case where I had added just enough to get to 600 AI items. But this was in a case where they were all blank distribution quantities -- I suspect you need to make sure items.distribution_quantity reads as double as well.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aside - we may want to talk to the stakeholders about fractional people per month - because at small volumes, it's going to change the supplies per month depending on whether we do or not. We should, in any case, have how we handle it make sense to them.

end

def total_people_served_with_supplies_from_kits_per_month
organization
.distributions.for_year(year)
.joins(line_items: {item: :kit})
.merge(Item.adult_incontinence)
.where.not(items: {kit_id: nil})
.sum('line_items.quantity / COALESCE(items.distribution_quantity, 1)') / 12
end
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per the issue, "
The number of adults assisted with kit items is the number of kits that contain adult incontinence supplies distributed divided by the "quantity per individual" on the kit item. if there is no quantity per individual provided, assume that quantity is 1."

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quick question, also I apologize for missing that bit! Is it a safe assumption that the distribution_quantity is equal to the "quantity per individual"?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Sorry for the terminology ambiguity -- they are the same.

Copy link
Collaborator

@cielf cielf Dec 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect this is giving you kits that are identified as adult_incontinence, rather than kits that have adult incontinence items in them? Though you used the same pattern as for the disposables... Huh.

end
end
32 changes: 26 additions & 6 deletions spec/services/reports/adult_incontinence_report_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
it 'should report zero values' do
expect(report.report[:name]).to eq("Adult Incontinence")
expect(report.report[:entries]).to match(hash_including({
"Adult incontinence supplies distributed" => 0,
"Adults Assisted Per Month" => 0,
"% adult incontinence bought" => "0%",
"% adult incontinence supplies donated" => "0%",
"Adult incontinence supplies distributed" => "0",
Expand Down Expand Up @@ -40,6 +42,14 @@
adult_incontinence_item = organization.items.adult_incontinence.first
non_adult_incontinence_item = organization.items.where.not(id: organization.items.adult_incontinence).first

# kits
kit = create(:kit, organization: organization)

create(:base_item, name: "Adult Pads", partner_key: "adult pads", category: "adult pads")
create(:base_item, name: "Adult wipes", partner_key: "adult wipes", category: "adult wipes")

adult_kit_item_1 = create(:item, name: "Adult Pads", partner_key: "adult pads", kit: kit)
adult_kit_item_2 = create(:item, name: "Adult Wipes", partner_key: "adult wipes", kit: kit)
# We will create data both within and outside our date range, and both adult_incontinence and non adult_incontinence.
# Spec will ensure that only the required data is included.

Expand All @@ -51,6 +61,12 @@
create_list(:line_item, 5, :distribution, quantity: 30, item: non_adult_incontinence_item, itemizable: dist)
end

kit_distribution_1 = create(:distribution, organization: organization, issued_at: within_time)
kit_distribution_2 = create(:distribution, organization: organization, issued_at: within_time)

create(:line_item, :distribution, quantity: 10, item: adult_kit_item_1, itemizable: kit_distribution_1)
create(:line_item, :distribution, quantity: 10, item: adult_kit_item_2, itemizable: kit_distribution_2)

# Donations
donations = create_list(:donation, 2,
product_drive: nil,
Expand Down Expand Up @@ -102,8 +118,9 @@
expect(report.report[:entries]).to match(hash_including({
"% adult incontinence bought" => "60%",
"% adult incontinence supplies donated" => "40%",
"Adult incontinence supplies distributed" => "2,000",
"Adult incontinence supplies per adult per month" => 20,
"Adults Assisted Per Month" => 9,
"Adult incontinence supplies distributed" => "2,040",
"Adult incontinence supplies per adult per month" => 2,
"Money spent purchasing adult incontinence supplies" => "$30.00"
}))
expect(report.report[:entries]['Adult incontinence supplies'].split(', '))
Expand All @@ -117,16 +134,18 @@
"Adult Incontinence Pads",
"Underpads (Pack)",
"Adult Liners",
"Wipes (Adult)")
"Wipes (Adult)",
"1T Diapers")
end

it 'should handle null distribution quantity' do
expect(report.report[:name]).to eq("Adult Incontinence")
expect(report.report[:entries]).to match(hash_including({
"% adult incontinence bought" => "60%",
"% adult incontinence supplies donated" => "40%",
"Adult incontinence supplies distributed" => "2,000",
"Adult incontinence supplies per adult per month" => 50,
"Adult incontinence supplies distributed" => "2,040",
"Adults Assisted Per Month" => 4,
"Adult incontinence supplies per adult per month" => 12,
"Money spent purchasing adult incontinence supplies" => "$30.00"
}))
expect(report.report[:entries]['Adult incontinence supplies'].split(', '))
Expand All @@ -140,7 +159,8 @@
"Adult Incontinence Pads",
"Underpads (Pack)",
"Adult Liners",
"Wipes (Adult)")
"Wipes (Adult)",
"2T Diapers")
end
end
end
Expand Down