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 events to seeds + make DistributionCreateService consistent #3979

Merged
merged 3 commits into from
Dec 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion app/controllers/distributions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ def index
end

def create
result = DistributionCreateService.new(distribution_params.merge(organization: current_organization), request_id).call
dist = Distribution.new(distribution_params.merge(organization: current_organization))
result = DistributionCreateService.new(dist, request_id).call

if result.success?
session[:created_distribution_id] = result.distribution.id
Expand Down
4 changes: 2 additions & 2 deletions app/services/distribution_create_service.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
class DistributionCreateService < DistributionService
attr_reader :distribution

def initialize(distribution_params, request_id = nil)
@distribution = Distribution.new(distribution_params)
def initialize(distribution, request_id = nil)
@distribution = distribution
@request = Request.find(request_id) if request_id
end

Expand Down
93 changes: 41 additions & 52 deletions db/seeds.rb
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ def random_record_for_org(org, klass)
partner_user_id: p.primary_user.id
)

item_requests = []
item_requests = []
Array.new(Faker::Number.within(range: 5..15)) do
item = p.organization.items.sample
new_item_request = Partners::ItemRequest.new(
Expand Down Expand Up @@ -388,6 +388,7 @@ def random_record_for_org(org, klass)
)
end
end
Organization.all.each { |org| SnapshotEvent.publish(org) }

# ----------------------------------------------------------------------------
# Product Drives
Expand Down Expand Up @@ -458,13 +459,8 @@ def seed_quantity(item_name, organization, storage_location, quantity)
storage_location: storage_location,
user: User.with_role(:org_admin, organization).first
)

LineItem.create!(quantity: quantity, item: item, itemizable: adjustment)

adjustment.reload
increasing_adjustment, decreasing_adjustment = adjustment.split_difference
adjustment.storage_location.increase_inventory increasing_adjustment
adjustment.storage_location.decrease_inventory decreasing_adjustment
adjustment.line_items = [LineItem.new(quantity: quantity, item: item, itemizable: adjustment)]
AdjustmentCreateService.new(adjustment).call
end

items_by_category.each do |_category, entries|
Expand Down Expand Up @@ -508,64 +504,54 @@ def seed_quantity(item_name, organization, storage_location, quantity)
20.times.each do
source = Donation::SOURCES.values.sample
# Depending on which source it uses, additional data may need to be provided.
donation = case source
when Donation::SOURCES[:product_drive]
Donation.create! source: source,
product_drive: ProductDrive.first,
product_drive_participant: random_record_for_org(pdx_org, ProductDriveParticipant),
storage_location: random_record_for_org(pdx_org, StorageLocation),
organization: pdx_org,
issued_at: Time.zone.now
when Donation::SOURCES[:donation_site]
Donation.create! source: source,
donation_site: random_record_for_org(pdx_org, DonationSite),
storage_location: random_record_for_org(pdx_org, StorageLocation),
organization: pdx_org,
issued_at: Time.zone.now
when Donation::SOURCES[:manufacturer]
Donation.create! source: source,
manufacturer: random_record_for_org(pdx_org, Manufacturer),
storage_location: random_record_for_org(pdx_org, StorageLocation),
organization: pdx_org,
issued_at: Time.zone.now
else
Donation.create! source: source,
storage_location: random_record_for_org(pdx_org, StorageLocation),
organization: pdx_org,
issued_at: Time.zone.now
end
donation = Donation.new(source: source,
storage_location: random_record_for_org(pdx_org, StorageLocation),
organization: pdx_org, issued_at: Time.zone.now)
case source
when Donation::SOURCES[:product_drive]
donation.product_drive = ProductDrive.first
donation.product_drive_participant = random_record_for_org(pdx_org, ProductDriveParticipant)
when Donation::SOURCES[:donation_site]
donation.donation_site = random_record_for_org(pdx_org, DonationSite)
when Donation::SOURCES[:manufacturer]
donation.manufacturer = random_record_for_org(pdx_org, Manufacturer)
end

rand(1..5).times.each do
LineItem.create! quantity: rand(250..500), item: random_record_for_org(pdx_org, Item), itemizable: donation
donation.line_items.push(LineItem.new(quantity: rand(250..500), item: random_record_for_org(pdx_org, Item)))
end
donation.reload
donation.storage_location.increase_inventory(donation)
DonationCreateService.call(donation)
end

# ----------------------------------------------------------------------------
# Distributions
# ----------------------------------------------------------------------------

inventory = InventoryAggregate.inventory_for(pdx_org.id)
# Make some distributions, but don't use up all the inventory
20.times.each do
storage_location = random_record_for_org(pdx_org, StorageLocation)
stored_inventory_items_sample = storage_location.inventory_items.sample(20)
stored_inventory_items_sample = inventory.storage_locations[storage_location.id].items.values.sample(20)
delivery_method = Distribution.delivery_methods.keys.sample
shipping_cost = delivery_method == "shipped" ? (rand(20.0..100.0)).round(2).to_s : nil
distribution = Distribution.create!(storage_location: storage_location,
partner: random_record_for_org(pdx_org, Partner),
organization: pdx_org,
issued_at: Faker::Date.between(from: 4.days.ago, to: Time.zone.today),
delivery_method: delivery_method,
shipping_cost: shipping_cost,
comment: 'Urgent')
distribution = Distribution.new(
storage_location: storage_location,
partner: random_record_for_org(pdx_org, Partner),
organization: pdx_org,
issued_at: Faker::Date.between(from: 4.days.ago, to: Time.zone.today),
delivery_method: delivery_method,
shipping_cost: shipping_cost,
comment: 'Urgent'
)

stored_inventory_items_sample.each do |stored_inventory_item|
distribution_qty = rand(stored_inventory_item.quantity / 2)
LineItem.create! quantity: distribution_qty, item: stored_inventory_item.item, itemizable: distribution if distribution_qty >= 1
if distribution_qty >= 1
distribution.line_items.push(LineItem.new(quantity: distribution_qty,
item_id: stored_inventory_item.item_id))
end
end
distribution.reload
distribution.storage_location.decrease_inventory(distribution)
DistributionCreateService.new(distribution).call
end

# ----------------------------------------------------------------------------
Expand Down Expand Up @@ -636,7 +622,7 @@ def seed_quantity(item_name, organization, storage_location, quantity)
20.times do
storage_location = random_record_for_org(pdx_org, StorageLocation)
vendor = random_record_for_org(pdx_org, Vendor)
Purchase.create(
purchase = Purchase.new(
purchased_from: suppliers.sample,
comment: comments.sample,
organization_id: pdx_org.id,
Expand All @@ -647,13 +633,14 @@ def seed_quantity(item_name, organization, storage_location, quantity)
updated_at: (Time.zone.today - rand(15).days),
vendor_id: vendor.id
)
PurchaseCreateService.call(purchase)
end

#re 2813_update_annual_report add some data for last year (enables system testing of reports)
5.times do
storage_location = random_record_for_org(pdx_org, StorageLocation)
vendor = random_record_for_org(pdx_org, Vendor)
Purchase.create(
purchase = Purchase.new(
purchased_from: suppliers.sample,
comment: comments.sample,
organization_id: pdx_org.id,
Expand All @@ -664,6 +651,7 @@ def seed_quantity(item_name, organization, storage_location, quantity)
updated_at: (Time.zone.today - 1.year),
vendor_id: vendor.id
)
PurchaseCreateService.call(purchase)
end


Expand Down Expand Up @@ -780,12 +768,13 @@ def seed_quantity(item_name, organization, storage_location, quantity)
# ----------------------------------------------------------------------------
# Transfers
# ----------------------------------------------------------------------------
Transfer.create!(
transfer = Transfer.new(
comment: Faker::Lorem.sentence,
organization_id: pdx_org.id,
from_id: pdx_org.id,
to_id: sf_org.id,
line_items: [
LineItem.create!(quantity: 5, item: pdx_org.items.first, itemizable: Distribution.first)
LineItem.new(quantity: 5, item: pdx_org.items.first)
]
)
TransferCreateService.call(transfer)
62 changes: 42 additions & 20 deletions spec/services/distribution_create_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,25 @@
subject { DistributionCreateService }
describe "call" do
let!(:storage_location) { create(:storage_location, :with_items, item_count: 2) }
let!(:distribution_params) { { organization_id: @organization.id, partner_id: @partner.id, storage_location_id: storage_location.id, delivery_method: :delivery, line_items_attributes: { "0": { item_id: storage_location.items.first.id, quantity: 5 } } } }
let!(:distribution) {
Distribution.new(organization_id: @organization.id,
partner_id: @partner.id,
storage_location_id: storage_location.id,
delivery_method: :delivery,
line_items_attributes: {
"0": { item_id: storage_location.items.first.id, quantity: 5 }
})
}

it "replaces a big distribution with a smaller one, resulting in increased stored quantities" do
expect do
subject.new(distribution_params).call
subject.new(distribution).call
end.to change { storage_location.reload.size }.by(-5)
.and change { DistributionEvent.count }.by(1)
end

it "returns a successful object with Scheduled distribution" do
result = subject.new(distribution_params).call
result = subject.new(distribution).call
expect(result).to be_instance_of(subject)
expect(result).to be_success
expect(result.distribution).to be_scheduled
Expand All @@ -26,7 +34,7 @@

expect do
perform_enqueued_jobs only: PartnerMailerJob do
subject.new(distribution_params).call
subject.new(distribution).call
end
end.to change { ActionMailer::Base.deliveries.count }.by(1)
end
Expand All @@ -37,7 +45,7 @@
@partner.update!(send_reminders: false)

expect(PartnerMailerJob).not_to receive(:perform_later)
subject.new(distribution_params).call
subject.new(distribution).call
end
end

Expand All @@ -47,7 +55,7 @@

expect do
perform_enqueued_jobs only: PartnerMailerJob do
subject.new(distribution_params).call
subject.new(distribution).call
end
end.not_to change { ActionMailer::Base.deliveries.count }
end
Expand All @@ -58,7 +66,7 @@

it "changes the status of the request" do
expect do
subject.new(distribution_params, request.id).call
subject.new(distribution, request.id).call
request.reload
end.to change { request.status }
end
Expand All @@ -70,26 +78,34 @@
end

it 'should not be successful' do
result = subject.new(distribution_params, request.id).call
result = subject.new(distribution, request.id).call
expect(result.error.message).to eq("Request has already been fulfilled by Distribution #{distribution.id}")
expect(result).not_to be_success
end
end
end

context "when there's not sufficient inventory" do
let(:too_much_params) { { organization_id: @organization.id, partner_id: @partner.id, storage_location_id: storage_location.id, delivery_method: :delivery, line_items_attributes: { "0": { item_id: storage_location.items.first.id, quantity: 500 } } } }
let(:too_much_dist) {
Distribution.new(
organization_id: @organization.id,
partner_id: @partner.id,
storage_location_id: storage_location.id,
delivery_method: :delivery,
line_items_attributes: { "0": { item_id: storage_location.items.first.id, quantity: 500 } }
)
}

it "preserves the Insufficiency error and is unsuccessful" do
result = subject.new(too_much_params).call
result = subject.new(too_much_dist).call
expect(result.error).to be_instance_of(Errors::InsufficientAllotment)
expect(result).not_to be_success
end
end

context "when there's multiple line items and one has insufficient inventory" do
let(:too_much_params) do
{
let(:too_much_dist) do
Distribution.new(
organization_id: @organization.id,
partner_id: @partner.id,
storage_location_id: storage_location.id,
Expand All @@ -99,39 +115,45 @@
"0": { item_id: storage_location.items.first.id, quantity: 2 },
"1": { item_id: storage_location.items.last.id, quantity: 500 }
}
}
)
end

it "preserves the Insufficiency error and is unsuccessful" do
result = subject.new(too_much_params).call
result = subject.new(too_much_dist).call
expect(result.error).to be_instance_of(Errors::InsufficientAllotment)
expect(result).not_to be_success
end
end

context "when it fails to save" do
let(:bad_params) { { organization_id: @organization.id, storage_location_id: storage_location.id, line_items_attributes: { "0": { item_id: storage_location.items.first.id, quantity: 500 } } } }
let(:bad_dist) {
Distribution.new(organization_id: @organization.id,
storage_location_id: storage_location.id,
line_items_attributes: {
"0": { item_id: storage_location.items.first.id, quantity: 500 }
})
}

it "preserves the error and is unsuccessful" do
result = subject.new(bad_params).call
result = subject.new(bad_dist).call
expect(result.error).to be_instance_of(ActiveRecord::RecordInvalid)
expect(result).not_to be_success
end
end

context "when the line item quantity is not positive" do
let(:params) {
{
let(:dist) {
Distribution.new(
organization_id: @organization.id,
partner_id: @partner.id,
storage_location_id: storage_location.id,
delivery_method: :delivery,
line_items_attributes: { "0": { item_id: storage_location.items.first.id, quantity: 0 } }
}
)
}

it "preserves the RecordInvalid error and is unsuccessful" do
result = subject.new(params).call
result = subject.new(dist).call
expect(result.error).to be_instance_of(ActiveRecord::RecordInvalid)
expect(result).not_to be_success
end
Expand Down
Loading