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

Add models to support request units #4306

Merged
merged 16 commits into from
May 24, 2024
1 change: 1 addition & 0 deletions app/models/item.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class Item < ApplicationRecord
has_many :storage_locations, through: :inventory_items
has_many :donations, through: :line_items, source: :itemizable, source_type: "::Donation"
has_many :distributions, through: :line_items, source: :itemizable, source_type: "::Distribution"
has_many :request_units, class_name: "ItemUnit", dependent: :destroy

scope :active, -> { where(active: true) }

Expand Down
20 changes: 20 additions & 0 deletions app/models/item_unit.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# == Schema Information
#
# Table name: item_units
#
# id :bigint not null, primary key
# name :string not null
# created_at :datetime not null
# updated_at :datetime not null
# item_id :bigint
#
class ItemUnit < ApplicationRecord
belongs_to :item

validate do
names = item.organization.request_units.map(&:name)
unless names.include?(name)
errors.add(:name, "is not supported by the organization")
end
end
end
1 change: 1 addition & 0 deletions app/models/organization.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ class Organization < ApplicationRecord
has_many :transfers
has_many :users, -> { distinct }, through: :roles
has_many :vendors
has_many :request_units, class_name: 'Unit'
end

has_many :items, dependent: :destroy do
Expand Down
12 changes: 12 additions & 0 deletions app/models/partners/item_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
# name :string
# partner_key :string
# quantity :string
# request_unit :string
# created_at :datetime not null
# updated_at :datetime not null
# item_id :integer
Expand All @@ -16,12 +17,23 @@ module Partners
class ItemRequest < Base
has_paper_trail
belongs_to :request, class_name: '::Request', foreign_key: :partner_request_id, inverse_of: :item_requests
belongs_to :item
has_many :child_item_requests, dependent: :destroy
has_many :children, through: :child_item_requests

validates :quantity, presence: true
validates :quantity, numericality: { only_integer: true, greater_than_or_equal_to: 1 }
validates :name, presence: true
validates :partner_key, presence: true
validate :request_unit_is_supported

def request_unit_is_supported
return if request_unit.blank?

names = item.request_units.map(&:name)
unless names.include?(request_unit)

This comment was marked as outdated.

errors.add(:request_unit, "is not supported")
end
end
end
end
13 changes: 13 additions & 0 deletions app/models/unit.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# == Schema Information
#
# Table name: units
#
# id :bigint not null, primary key
# name :string not null
# created_at :datetime not null
# updated_at :datetime not null
# organization_id :bigint
#
class Unit < ApplicationRecord
belongs_to :organization
end
16 changes: 16 additions & 0 deletions db/migrate/20240426135118_add_pack_models.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class AddPackModels < ActiveRecord::Migration[7.0]
def change
create_table :units do |t|
t.string :name, null: false
t.references :organization, foreign_key: true
t.timestamps
end

create_table :item_units do |t|
t.string :name, null: false
t.references :item, foreign_key: true
t.timestamps
end

end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddRequestUnitsToItemRequests < ActiveRecord::Migration[7.0]
def change
add_column :item_requests, :request_unit, :string
end
cielf marked this conversation as resolved.
Show resolved Hide resolved
end
21 changes: 20 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,8 @@
t.integer "organization_id"
t.datetime "issued_at", precision: nil
t.string "agency_rep"
t.boolean "reminder_email_enabled", default: false, null: false
t.integer "state", default: 5, null: false
t.boolean "reminder_email_enabled", default: false, null: false
t.integer "delivery_method", default: 0, null: false
t.decimal "shipping_cost", precision: 8, scale: 2
t.index ["organization_id"], name: "index_distributions_on_organization_id"
Expand Down Expand Up @@ -381,10 +381,19 @@
t.string "partner_key"
t.integer "item_id"
t.integer "old_partner_request_id"
t.string "request_unit"
t.index ["item_id"], name: "index_item_requests_on_item_id"
t.index ["partner_request_id"], name: "index_item_requests_on_partner_request_id"
end

create_table "item_units", force: :cascade do |t|
t.string "name", null: false
t.bigint "item_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["item_id"], name: "index_item_units_on_item_id"
end

create_table "items", id: :serial, force: :cascade do |t|
t.string "name"
t.string "category"
Expand Down Expand Up @@ -782,6 +791,14 @@
t.index ["organization_id"], name: "index_transfers_on_organization_id"
end

create_table "units", force: :cascade do |t|
t.string "name", null: false
t.bigint "organization_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["organization_id"], name: "index_units_on_organization_id"
end

create_table "users", id: :serial, force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
Expand Down Expand Up @@ -880,6 +897,7 @@
add_foreign_key "item_categories", "organizations"
add_foreign_key "item_categories_partner_groups", "item_categories"
add_foreign_key "item_categories_partner_groups", "partner_groups"
add_foreign_key "item_units", "items"
add_foreign_key "items", "item_categories"
add_foreign_key "items", "kits"
add_foreign_key "kit_allocations", "kits"
Expand All @@ -898,5 +916,6 @@
add_foreign_key "requests", "distributions"
add_foreign_key "requests", "organizations"
add_foreign_key "requests", "partners"
add_foreign_key "units", "organizations"
add_foreign_key "users", "users_roles", column: "last_role_id", on_delete: :nullify
end
38 changes: 34 additions & 4 deletions db/seeds.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@
return
end

# Activate all feature flags
Flipper.enable(:onebase)

# ----------------------------------------------------------------------------
# Random Record Generators
# ----------------------------------------------------------------------------
Expand Down Expand Up @@ -80,6 +77,26 @@ def random_record_for_org(org, klass)
end
end

# ----------------------------------------------------------------------------
# Request Units
# ----------------------------------------------------------------------------

%w(pack box flat).each do |name|
Unit.create!(organization: pdx_org, name: name)
end

pdx_org.items.each_with_index do |item, i|
if item.name == 'Pads'
%w(box pack).each { |name| item.request_units.create!(name: name) }
elsif item.name == 'Wipes (Baby)'
item.request_units.create!(name: 'pack')
elsif item.name == 'Kids Pull-Ups (5T-6T)'
%w(pack flat).each do |name|
item.request_units.create!(name: name)
end
end
end

# ----------------------------------------------------------------------------
# Item Categories
# ----------------------------------------------------------------------------
Expand Down Expand Up @@ -337,7 +354,20 @@ def random_record_for_org(org, klass)
)

item_requests = []
Array.new(Faker::Number.within(range: 5..15)) do
pads = p.organization.items.find_by(name: 'Pads')
new_item_request = Partners::ItemRequest.new(
item_id: pads.id,
quantity: Faker::Number.within(range: 10..30),
children: [],
name: pads.name,
partner_key: pads.partner_key,
created_at: date,
updated_at: date,
request_unit: 'pack'
)
partner_request.item_requests << new_item_request

Array.new(Faker::Number.within(range: 4..14)) do
item = p.organization.items.sample
new_item_request = Partners::ItemRequest.new(
item_id: item.id,
Expand Down
20 changes: 20 additions & 0 deletions spec/factories/item_units.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# == Schema Information
#
# Table name: item_units
#
# id :bigint not null, primary key
# name :string not null
# created_at :datetime not null
# updated_at :datetime not null
# item_id :bigint
#
FactoryBot.define do
factory :item_unit do
sequence(:name) { |n| "Unit #{n}" }
item

before(:create) do |unit, _|
unit.item.organization.request_units.find_or_create_by(name: unit.name)
end
end
end
9 changes: 9 additions & 0 deletions spec/factories/partners/item_request.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FactoryBot.define do
factory :item_request, class: Partners::ItemRequest do
item
request { build(:request, organization: item.organization) }
quantity { 5 }
sequence(:name) { |n| "Item Request #{n}" }
sequence(:partner_key) { |n| "partner_key#{n}" }
end
end
16 changes: 16 additions & 0 deletions spec/factories/units.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# == Schema Information
#
# Table name: units
#
# id :bigint not null, primary key
# name :string not null
# created_at :datetime not null
# updated_at :datetime not null
# organization_id :bigint
#
FactoryBot.define do
factory :unit do
sequence(:name) { |n| "Unit #{n}" }
organization
end
end
25 changes: 25 additions & 0 deletions spec/models/item_unit_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# == Schema Information
#
# Table name: item_request_units
#
# id :bigint not null, primary key
# name :string not null
# created_at :datetime not null
# updated_at :datetime not null
# item_id :bigint
#
RSpec.describe ItemUnit, type: :model do
context "Validations >" do
let(:organization) { create(:organization) }
let(:item) { create(:item, organization: organization) }
it "should only be valid if the organization has a corresponding unit" do
item_unit = build(:item_unit, item: item, name: "pack")
expect(item_unit.valid?).to eq(false)
expect(item_unit.errors.full_messages).to eq(["Name is not supported by the organization"])

create(:unit, organization: organization, name: "pack")
organization.reload
expect(item_unit.valid?).to eq(true)
end
end
end
19 changes: 19 additions & 0 deletions spec/models/partners/item_request_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
# name :string
# partner_key :string
# quantity :string
# request_unit :string
# created_at :datetime not null
# updated_at :datetime not null
# item_id :integer
Expand All @@ -15,6 +16,7 @@
require "rails_helper"

RSpec.describe Partners::ItemRequest, type: :model do
let(:organization) { create(:organization) }
describe 'associations' do
it { should belong_to(:request).class_name('::Request').with_foreign_key(:partner_request_id) }
it { should have_many(:child_item_requests).dependent(:destroy) }
Expand All @@ -26,6 +28,23 @@
it { should validate_numericality_of(:quantity).only_integer.is_greater_than_or_equal_to(1) }
it { should validate_presence_of(:name) }
it { should validate_presence_of(:partner_key) }

it "should only be able to use item's request units" do
create(:unit, organization: organization, name: 'pack')
create(:unit, organization: organization, name: 'flat')
item = create(:item, organization: organization)
item_unit = create(:item_unit, name: 'pack', item: item)
request = build(:request, organization: organization)

item_request = build(:item_request, request_unit: "flat", request: request, item: item)

expect(item_request.valid?).to eq(false)
expect(item_request.errors.full_messages).to eq(["Request unit is not supported"])

item_unit.update!(name: 'flat')
item.reload
expect(item_request.valid?).to eq(true)
end
cielf marked this conversation as resolved.
Show resolved Hide resolved
end

describe "versioning" do
Expand Down