Skip to content

Commit 408b0a4

Browse files
Merge branch 'main' into 4946-partner-profile-export
2 parents bc5735d + d8fa236 commit 408b0a4

69 files changed

Lines changed: 1147 additions & 688 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

app/assets/stylesheets/simple_form-bootstrap/_form_multi_select.scss

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,10 @@
1616
margin-left: 0 !important;
1717
margin-right: 0 !important;
1818
}
19-
}
19+
}
20+
21+
.input-group, .form-group {
22+
select {
23+
@extend .form-select;
24+
}
25+
}

app/controllers/admin/users_controller.rb

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# [Super Admin] This is for administrating users at a global level. We can create, view, modify, etc.
22
class Admin::UsersController < AdminController
3-
before_action :load_organizations, only: %i[new create edit update]
3+
before_action :load_organizations, only: %i[create edit update]
44
before_action :user_params, only: %i[create update]
55

66
def index
@@ -34,15 +34,19 @@ def new
3434

3535
def edit
3636
@user = User.find_by(id: params[:id])
37-
@resources = Role.resources_for_select
3837
end
3938

4039
def create
4140
@user = User.new(user_params)
42-
UserInviteService.invite(name: user_params[:name],
41+
validate_role_resource_params
42+
klass = Role::TITLE_TO_RESOURCE[params[:resource_type].to_sym]
43+
resource = klass&.find(params[:resource_id])
44+
UserInviteService.invite(
45+
name: user_params[:name],
4346
email: user_params[:email],
44-
roles: [Role::ORG_USER],
45-
resource: Organization.find(organization_id_param))
47+
roles: [params[:resource_type].to_sym],
48+
resource: resource
49+
)
4650
flash[:notice] = "Created a new user!"
4751
redirect_to admin_users_path
4852
rescue => e
@@ -95,12 +99,9 @@ def user_params
9599
params.require(:user).permit(:name, :email)
96100
end
97101

98-
def organization_id_param
99-
organization_id = params[:user][:organization_id]
100-
101-
raise "Please select an organization for the user." if organization_id.blank?
102-
103-
organization_id
102+
def validate_role_resource_params
103+
raise "Please select a role for the user." if params[:resource_type].blank?
104+
raise "Please select an associated resource for the role." if !Role::ROLES_WITHOUT_RESOURCE.map(&:to_s).include?(params[:resource_type]) && params[:resource_id].blank?
104105
end
105106

106107
def load_organizations

app/controllers/concerns/importable.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ module Importable
2525
def import_csv
2626
if params[:file].present?
2727
data = File.read(params[:file].path, encoding: "BOM|UTF-8")
28-
csv = CSV.parse(data, headers: true).reject { |row| row.to_hash.values.any?(&:nil?) }
28+
csv = CSV.parse(data, headers: true)
2929
if csv.count.positive? && csv.first.headers.all? { |header| !header.nil? }
3030
errors = resource_model.import_csv(csv, current_organization.id)
3131
if errors.empty?

app/controllers/partner_users_controller.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ def create
2424
@users = @partner.users
2525
render :index
2626
end
27+
rescue => e
28+
flash[:error] = e.message
29+
redirect_to partner_users_path(@partner)
2730
end
2831

2932
def destroy

app/helpers/items_helper.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,8 @@ def selected_item_request_units(item)
1919
item_request_unit_names = item.persisted? ? item.request_units.pluck(:name) : []
2020
current_organization.request_units.select { |unit| item_request_unit_names.include?(unit.name) }.pluck(:id)
2121
end
22+
23+
def quantity_below_minimum?(row_item)
24+
row_item[:quantity] < row_item[:item_on_hand_minimum_quantity]
25+
end
2226
end
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { Controller } from "@hotwired/stimulus"
2+
3+
export default class extends Controller {
4+
static targets = ["source", "destination"]
5+
static values = {
6+
valuesToHide: Array
7+
}
8+
sourceChanged() {
9+
const val = $(this.sourceTarget).val()
10+
this.destinationTargets.forEach(
11+
destination_target => { $(destination_target).toggleClass("d-none", this.valuesToHideValue.includes(val)); }
12+
)
13+
}
14+
}

app/models/base_item.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class BaseItem < ApplicationRecord
3939
"Adult Briefs (XXXL)" => "adult_incontinence",
4040
"Adult Cloth Diapers (Large/XL/XXL)" => "adult_incontinence",
4141
"Adult Cloth Diapers (Small/Medium)" => "adult_incontinence",
42-
"adult_incontinence Pads" => "adult_incontinence",
42+
"Adult Incontinence Pads" => "adult_incontinence",
4343
"Bed Pads (Cloth)" => "other",
4444
"Bed Pads (Disposable)" => "other",
4545
"Bibs (Adult & Child)" => "other",
@@ -69,7 +69,7 @@ class BaseItem < ApplicationRecord
6969
"Kids S/M (38-65 lbs)" => "disposable_diapers",
7070
"Kit" => nil,
7171
"Liners (Incontinence)" => "adult_incontinence",
72-
"Liners (Menstrual)" => "menstrual",
72+
"Liners (Menstrual)" => "period_liners",
7373
"Other" => "other",
7474
"Pads" => "pads",
7575
"Swimmers" => "disposable_diapers",

app/models/distribution.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class Distribution < ApplicationRecord
4747
enum :state, { scheduled: 5, complete: 10 }
4848
enum :delivery_method, { pick_up: 0, delivery: 1, shipped: 2 }
4949
scope :active, -> { joins(:line_items).joins(:items).where(items: { active: true }) }
50-
scope :with_diapers, -> { joins(line_items: :item).merge(Item.disposable.or(Item.cloth_diapers)) }
50+
scope :with_diapers, -> { joins(line_items: :item).merge(Item.disposable_diapers.or(Item.cloth_diapers)) }
5151
scope :with_period_supplies, -> { joins(line_items: :item).merge(Item.period_supplies) }
5252
# add item_id scope to allow filtering distributions by item
5353
scope :by_item_id, ->(item_id) { includes(:items).where(items: { id: item_id }) }

app/models/donation_site.rb

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class DonationSite < ApplicationRecord
2323
belongs_to :organization
2424

2525
validates :name, :address, presence: true
26+
validates :name, uniqueness: {scope: :organization_id, message: "must be unique within the organization"}
2627
validates :contact_name, length: {minimum: 3}, allow_blank: true
2728
validates :email, format: {with: URI::MailTo::EMAIL_REGEXP, message: "is not a valid email format"}, allow_blank: true
2829

@@ -36,12 +37,17 @@ class DonationSite < ApplicationRecord
3637
scope :alphabetized, -> { order(:name) }
3738

3839
def self.import_csv(csv, organization)
39-
csv.each do |row|
40+
errors = []
41+
csv.each_with_index do |row, index|
4042
loc = DonationSite.new(row.to_hash)
4143
loc.organization_id = organization
42-
loc.save!
44+
if loc.save
45+
Rails.logger.info "Successfully imported: #{loc.name}"
46+
else
47+
errors << "Row #{index + 2}, #{row.to_hash["name"]} - #{loc.errors.full_messages.join(", ")}"
48+
end
4349
end
44-
[]
50+
errors
4551
end
4652

4753
def self.csv_export_headers

app/models/item.rb

Lines changed: 6 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -67,56 +67,22 @@ class Item < ApplicationRecord
6767

6868
scope :by_size, ->(size) { joins(:base_item).where(base_items: { size: size }) }
6969

70-
# Scopes - explanation of business rules for filtering scopes as of 20240527. This was a mess, but is much better now.
71-
# 1/ Disposable. Disposables are only the disposable diapers for children. So we deliberately exclude adult and cloth
72-
# 2/ Cloth. Cloth diapers for children. Exclude adult cloth. Cloth training pants also go here.
73-
# 3/ Adult incontinence. Items for adult incontinence -- diapers, ai pads, but not adult wipes.
74-
# 4/ Period supplies. All things with 'menstrual in the category'
75-
# 5/ Other -- Miscellaneous, and wipes
76-
# Known holes and ambiguities as of 20240527. Working on these with the business
77-
# 1/ Liners. We are adding a new item for AI liners, and renaming the current liners to be specifically for periods,
78-
# having confirmed with the business that the majority of liners are for menstrual use.
79-
# However, there is a product which can be used for either, so we are still sussing out what to do about that.
80-
81-
scope :disposable, -> {
82-
joins(:base_item)
83-
.where("lower(base_items.category) LIKE '%diaper%'")
84-
.where.not("lower(base_items.category) LIKE '%cloth%' OR lower(base_items.name) LIKE '%cloth%'")
85-
.where.not("lower(base_items.category) LIKE '%adult%'")
86-
}
87-
88-
scope :cloth_diapers, -> {
89-
joins(:base_item)
90-
.where("lower(base_items.category) LIKE '%cloth%'")
91-
.or(where("base_items.category = 'Training Pants'"))
92-
.where.not("lower(base_items.category) LIKE '%adult%'")
93-
}
94-
95-
scope :adult_incontinence, -> {
96-
joins(:base_item)
97-
.where("lower(base_items.category) LIKE '%adult%' AND lower(base_items.category) NOT LIKE '%wipes%'")
98-
}
99-
10070
scope :period_supplies, -> {
101-
joins(:base_item)
102-
.where("lower(base_items.category) LIKE '%menstrual%'")
103-
}
104-
105-
scope :other_categories, -> {
106-
joins(:base_item)
107-
.where("lower(base_items.category) LIKE '%wipes%'")
108-
.or(where("base_items.category = 'Miscellaneous'"))
71+
where(reporting_category: [:pads, :tampons, :period_liners, :period_underwear, :period_other])
10972
}
11073

11174
enum :reporting_category, {
11275
adult_incontinence: "adult_incontinence",
11376
cloth_diapers: "cloth_diapers",
11477
disposable_diapers: "disposable_diapers",
11578
menstrual: "menstrual",
116-
other: "other",
79+
other_categories: "other",
11780
pads: "pads",
81+
period_liners: "period_liners",
82+
period_other: "period_other",
83+
period_underwear: "period_underwear",
11884
tampons: "tampons"
119-
}, scopes: false, instance_methods: false
85+
}, instance_methods: false
12086

12187
def self.reactivate(item_ids)
12288
item_ids = Array.wrap(item_ids)

0 commit comments

Comments
 (0)