Skip to content
Open
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
29 changes: 3 additions & 26 deletions app/controllers/requests_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,16 @@ class RequestsController < ApplicationController
def index
setup_date_range_picker

@requests = current_organization
.ordered_requests
.undiscarded
.during(helpers.selected_range)
.class_filter(filter_params)
@unfulfilled_requests_count = current_organization.requests.where(status: [:pending, :started]).during(helpers.selected_range).class_filter(filter_params).count
@paginated_requests = @requests.includes(:partner).page(params[:page])
@calculate_product_totals = RequestsTotalItemsService.new(requests: @requests).calculate
@items = current_organization.items.alphabetized.select(:id, :name)
@partners = current_organization.partners.alphabetized.select(:id, :name, :status)
@statuses = Request.statuses.transform_keys(&:humanize)
@partner_users = User.where(id: @paginated_requests.map(&:partner_user_id)).select(:id, :name, :email)
@request_types = Request.request_types.transform_keys(&:humanize)
@selected_request_type = filter_params[:by_request_type]
@selected_request_item = filter_params[:by_request_item_id]
@selected_partner = filter_params[:by_partner]
@selected_status = filter_params[:by_status]
@requests_info = View::Requests.new(params: params, organization: current_organization, helpers: helpers)

respond_to do |format|
format.html
format.csv { send_data Exports::ExportRequestService.new(@requests).generate_csv, filename: "Requests-#{Time.zone.today}.csv" }
format.csv { send_data Exports::ExportRequestService.new(@requests_info.requests).generate_csv, filename: "Requests-#{Time.zone.today}.csv" }
end
end

def show
@request = current_organization.requests.find(params[:id])
@item_requests = @request.item_requests.includes(:item)

@inventory = View::Inventory.new(@request.organization_id)
@default_storage_location = @request.partner.default_storage_location_id || @request.organization.default_storage_location
@location = StorageLocation.find_by(id: @default_storage_location)

@custom_units = Flipper.enabled?(:enable_packs) && @request.item_requests.any? { |item| item.request_unit }
@request_info = View::RequestInfo.new(params:, organization: current_organization)
end

# Clicking the "New Distribution" button will set the the request to started
Expand Down
1 change: 0 additions & 1 deletion app/models/view/donations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ def from_params(params:, organization:, helpers:)
.includes(:storage_location,
:donation_site,
:product_drive,
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I am happy to remove this change from this PR. I got here by looking at other view objects and saw the bullet's warning: 8089be6cb25bfff90506e634fc486dbaf6454e9b

:product_drive_participant,
:manufacturer,
line_items: [:item])
.order(created_at: :desc)
Expand Down
33 changes: 33 additions & 0 deletions app/models/view/request_info.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
module View
class RequestInfo
attr_reader :request

def initialize(params:, organization:)
@request = organization.requests.find(params[:id])
end

def item_requests
@item_requests ||= @request.item_requests.includes(:item)
end

def inventory
@inventory ||= View::Inventory.new(@request.organization_id)
end

def default_storage_location
return @default_storage_location if defined?(@default_storage_location)

@efault_storage_location ||= @request.partner.default_storage_location_id || @request.organization.default_storage_location
end

def location
return @location if defined?(@location)

@location ||= StorageLocation.find_by(id: default_storage_location)
end

def custom_units
Flipper.enabled?(:enable_packs) && request.item_requests.any? { |item| item.request_unit }
end
end
end
79 changes: 79 additions & 0 deletions app/models/view/requests.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
module View
class Requests
include DateRangeHelper

attr_reader :filters, :helpers, :organization, :paginated_requests, :params, :requests

def initialize(params:, organization:, helpers:)
@params = params
@organization = organization
@filters = filter_params(params)
@helpers = helpers

@requests = organization
.ordered_requests
.undiscarded
.during(helpers.selected_range)
.class_filter(filters)

@paginated_requests = requests.includes(:partner).page(params[:page])
end

def filter_params(params = {})
if params.key?(:filters)
params.require(:filters).permit(:by_request_item_id, :by_partner, :by_status, :by_request_type)
else
{}
end
end

def unfulfilled_requests_count
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Same comment as above - please validate that methods are either memoized, only called once, or would not result in additional DB calls.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in e7257c0

@unfulfilled_requests_count ||= organization
.requests
.where(status: [:pending, :started])
.during(helpers.selected_range)
.class_filter(filters)
.count
end

def calculate_product_totals
@calculate_product_totals ||= RequestsTotalItemsService.new(requests: requests).calculate
end

def items
@items ||= organization.items.alphabetized.select(:id, :name)
end

def partners
@partners ||= organization.partners.alphabetized.select(:id, :name, :status)
end

def statuses
@statuses ||= Request.statuses.transform_keys(&:humanize)
end

def partner_users
@partner_users ||= User.where(id: paginated_requests.map(&:partner_user_id)).select(:id, :name, :email)
end

def request_types
@request_types ||= Request.request_types.transform_keys(&:humanize)
end

def selected_request_type
filters[:by_request_type]
end

def selected_request_item
filters[:by_request_item_id]
end

def selected_partner
filters[:by_partner]
end

def selected_status
filters[:by_status]
end
end
end
2 changes: 1 addition & 1 deletion app/views/requests/_calculate_product_totals.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
</tr>
</thead>
<tbody>
<% @calculate_product_totals.sort_by { |name, quantity| name.downcase }.each do |name, quantity| %>
<% @requests_info.calculate_product_totals.sort_by { |name, quantity| name.downcase }.each do |name, quantity| %>
<tr>
<td><%= name %></td>
<td><%= quantity %></td>
Expand Down
2 changes: 1 addition & 1 deletion app/views/requests/_new.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<div class="modal-body p-4">
<%= form_with(url: new_partners_request_path, method: :get) do |form| %>
<div class="form-group">
<%= form.collection_select(:partner_id, @partners.active, :id, :name, {include_blank: "Select a partner", required: true}, {class: "form-control mb-2"} ) %>
<%= form.collection_select(:partner_id, @requests_info.partners.active, :id, :name, {include_blank: "Select a partner", required: true}, {class: "form-control mb-2"} ) %>
</div>
<%= submit_button({text: "Next", icon: nil, name: ""}) %>
<% end %>
Expand Down
2 changes: 1 addition & 1 deletion app/views/requests/_request_row.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<td class="date"><%= request_row.created_at.strftime("%m/%d/%Y") %></td>
<td><%= request_row.partner.name %> </td>
<td>
<% partner_user = @partner_users.find { |pu| pu.id == request_row.partner_user_id } %>
<% partner_user = @requests_info.partner_users.find { |pu| pu.id == request_row.partner_user_id } %>
<%= "#{partner_user&.formatted_email}" %>
</td>
<td class="<%= quota_column_class(request_row.total_items, request_row.partner) %> text-right">
Expand Down
22 changes: 11 additions & 11 deletions app/views/requests/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,21 @@
<div class="card-body">
<%= form_tag(requests_path, method: :get) do |f| %>
<div class="row">
<% if @items.present? %>
<% if @requests_info.items.present? %>
<div class="form-group col-lg-3 col-md-3 col-sm-6 col-xs-12">
<%= filter_select(label: "Filter by item", scope: :by_request_item_id, collection: @items, selected: @selected_request_item) %>
<%= filter_select(label: "Filter by item", scope: :by_request_item_id, collection: @requests_info.items, selected: @requests_info.selected_request_item) %>
</div>
<% end %>
<% if @partners.present? %>
<% if @requests_info.partners.present? %>
<div class="form-group col-lg-3 col-md-3 col-sm-6 col-xs-12">
<%= filter_select(scope: :by_partner, collection: @partners, selected: @selected_partner) %>
<%= filter_select(scope: :by_partner, collection: @requests_info.partners, selected: @requests_info.selected_partner) %>
</div>
<% end %>
<div class="form-group col-lg-3 col-md-3 col-sm-6 col-xs-12">
<%= filter_select(scope: :by_request_type, collection: @request_types, key: :last, value: :first, selected: @selected_request_type) %>
<%= filter_select(scope: :by_request_type, collection: @requests_info.request_types, key: :last, value: :first, selected: @requests_info.selected_request_type) %>
</div>
<div class="form-group col-lg-3 col-md-3 col-sm-6 col-xs-12">
<%= filter_select(scope: :by_status, collection: @statuses, key: :last, value: :first, selected: @selected_status) %>
<%= filter_select(scope: :by_status, collection: @requests_info.statuses, key: :last, value: :first, selected: @requests_info.selected_status) %>
</div>
<div class="form-group col-lg-3 col-md-4 col-sm-6 col-xs-12">
<%= label_tag "Date Range" %>
Expand All @@ -67,13 +67,13 @@
<%= modal_button_to("#calculateTotals", {text: "Calculate Product Totals", icon: nil, size: "md", type: "success"}) %>
</div>
<div class="d-flex flex-wrap gap-2">
<% if @unfulfilled_requests_count > 0 %>
<% if @requests_info.unfulfilled_requests_count > 0 %>
<%= print_button_to(
print_unfulfilled_requests_path(format: :pdf, filters: filter_params.merge(date_range: date_range_params)),
text: "Print Unfulfilled Picklists (#{@unfulfilled_requests_count})",
text: "Print Unfulfilled Picklists (#{@requests_info.unfulfilled_requests_count})",
size: "md") %>
<% end %>
<%= download_button_to(requests_path(format: :csv, filters: filter_params.merge(date_range: date_range_params)), {text: "Export Requests", size: "md"}) if @requests.any? %>
<%= download_button_to(requests_path(format: :csv, filters: filter_params.merge(date_range: date_range_params)), {text: "Export Requests", size: "md"}) if @requests_info.requests.any? %>
<%= modal_button_to("#newRequest", text: "New Quantity Request", icon: "plus", type: "success") if current_user.has_role?(Role::ORG_ADMIN, current_organization) %>
</div>
</div>
Expand Down Expand Up @@ -112,13 +112,13 @@
</tr>
</thead>
<tbody>
<%= render partial: "request_row", collection: @paginated_requests %>
<%= render partial: "request_row", collection: @requests_info.paginated_requests %>
</tbody>
</table>
</div>
<!-- /.card-body -->
<div class="card-footer clearfix">
<%= paginate @paginated_requests %>
<%= paginate @requests_info.paginated_requests %>
</div>
<!-- /.card-footer-->
</div>
Expand Down
48 changes: 24 additions & 24 deletions app/views/requests/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
<div class="container-fluid">
<div class="row mb-2">
<div class="col-sm-6">
<% content_for :title, "Requests - #{@request.id} - #{current_organization.name}" %>
<% content_for :title, "Requests - #{@request_info.request.id} - #{current_organization.name}" %>
<h1>
Request
<small>from <%= @request.partner.name %></small>
<small>from <%= @request_info.request.partner.name %></small>
</h1>
</div>
<div class="col-sm-6">
Expand All @@ -15,8 +15,8 @@
<% end %>
</li>
<li class="breadcrumb-item"><%= link_to "Requests", requests_path %></li>
<li class="breadcrumb-item"><a href="#"> Request from <%= @request.partner.name %>
at <%= @request.created_at.to_fs(:distribution_date) %></a></li>
<li class="breadcrumb-item"><a href="#"> Request from <%= @request_info.request.partner.name %>
at <%= @request_info.request.created_at.to_fs(:distribution_date) %></a></li>
</ol>
</div>
</div>
Expand All @@ -29,7 +29,7 @@
<div class="col-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">This request was sent on <%= @request.created_at.to_fs(:distribution_date) %></h3>
<h3 class="card-title">This request was sent on <%= @request_info.request.created_at.to_fs(:distribution_date) %></h3>
</div>
<div class="card-body p-0">
<table class="table">
Expand All @@ -44,11 +44,11 @@
</thead>
<tbody>
<tr>
<td><%= @request.partner.name %></td>
<td><%= @request.partner_user&.formatted_email %></td>
<td><%= @request.request_type&.humanize %></td>
<td><%= render partial: "status", locals: {status: @request.status} %></td>
<td><%= @request.comments || 'None' %></td>
<td><%= @request_info.request.partner.name %></td>
<td><%= @request_info.request.partner_user&.formatted_email %></td>
<td><%= @request_info.request.request_type&.humanize %></td>
<td><%= render partial: "status", locals: {status: @request_info.request.status} %></td>
<td><%= @request_info.request.comments || 'None' %></td>
</tr>
</table>
</div>
Expand All @@ -67,48 +67,48 @@
<tr>
<th>Item</th>
<th>Quantity</th>
<% if @custom_units %>
<% if @request_info.custom_units %>
<th>Units (if applicable)</th>
<% end %>
<% if @default_storage_location %>
<% if @request_info.default_storage_location %>
<th>Default storage location inventory</th>
<% end %>
<th>Total Inventory</th>
</tr>
</thead>
<tbody>
<% @item_requests.each do |item_request| %>
<% @request_info.item_requests.each do |item_request| %>
<tr>
<td><%= item_request.item_name %></td>
<td><%= item_request.quantity %></td>
<% if @custom_units %>
<% if @request_info.custom_units %>
<td><%= item_request.request_unit&.pluralize(item_request.quantity.to_i) %></td>
<% end %>
<% if @default_storage_location %>
<% on_hand_for_location = @inventory.quantity_for(storage_location: @location&.id, item_id: item_request.item_id) %>
<% if @request_info.default_storage_location %>
<% on_hand_for_location = @request_info.inventory.quantity_for(storage_location: @request_info.location&.id, item_id: item_request.item_id) %>
<td><%= on_hand_for_location&.positive? ? on_hand_for_location : 'N/A' %></td>
<% end %>
<% on_hand = @inventory.quantity_for(item_id: item_request.item_id) %>
<% on_hand = @request_info.inventory.quantity_for(item_id: item_request.item_id) %>
<td><%= on_hand || 0 %></td>
</tr>
<% end %>
<tr>
<td>Total (Quota)</td>
<td>
<%= @request.total_items %>
<%= quota_display(@request.partner) %>
<%= @request_info.request.total_items %>
<%= quota_display(@request_info.request.partner) %>
</td>
<td />
</tr>
</tbody>
</table>
</div>
<div class="card-footer flex flex-row space-x-2">
<%= submit_button_to start_request_path(@request), {text: "Fulfill request", size: "md"} unless @request.distribution %>
<%= view_button_to(distribution_path(@request.distribution), {text: "View Associated Distribution", size: "md"}) if @request.distribution %>
<%= print_button_to print_picklist_request_path(@request), { format: :pdf, text: "Print", size: "md" } %>
<% unless @request.status_fulfilled? %>
<%= button_to 'Cancel', new_request_cancelation_path(request_id: @request.id),
<%= submit_button_to start_request_path(@request_info.request), {text: "Fulfill request", size: "md"} unless @request_info.request.distribution %>
<%= view_button_to(distribution_path(@request_info.request.distribution), {text: "View Associated Distribution", size: "md"}) if @request_info.request.distribution %>
<%= print_button_to print_picklist_request_path(@request_info.request), { format: :pdf, text: "Print", size: "md" } %>
<% unless @request_info.request.status_fulfilled? %>
<%= button_to 'Cancel', new_request_cancelation_path(request_id: @request_info.request.id),
method: :get, data: { disable_with: "Please wait..." }, form_class: 'd-inline', class: 'btn btn-danger btn-md' %>
<% end %>
</div>
Expand Down
Loading
Loading