Skip to content

Commit

Permalink
[rubyforgood#3052] Add confirmation modal for quantity requests
Browse files Browse the repository at this point in the history
  • Loading branch information
danielabar committed Jul 27, 2024
1 parent 3d073eb commit 8242bc9
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 3 deletions.
15 changes: 15 additions & 0 deletions app/controllers/partners/requests_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,21 @@ def create
end
end

def validate
@partner_request = Partners::RequestCreateService.new(
partner_user_id: current_user.id,
comments: partner_request_params[:comments],
item_requests_attributes: partner_request_params[:item_requests_attributes]&.values || []
).create_only

if @partner_request.valid?
body = render_to_string(template: 'partners/requests/validate', formats: [:html], layout: false)
render json: {valid: true, body: body}
else
render json: {valid: false}
end
end

private

def partner_request_params
Expand Down
8 changes: 8 additions & 0 deletions app/models/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ class Request < ApplicationRecord

validates :distribution_id, uniqueness: true, allow_nil: true
validate :item_requests_uniqueness_by_item_id
validate :not_completely_empty

before_save :sanitize_items_data

include Filterable
Expand Down Expand Up @@ -74,4 +76,10 @@ def sanitize_items_data
item.merge("item_id" => item["item_id"]&.to_i, "quantity" => item["quantity"]&.to_i)
end
end

def not_completely_empty
if comments.blank? && item_requests.blank?
errors.add(:base, "completely empty request")
end
end
end
10 changes: 10 additions & 0 deletions app/services/partners/request_create_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,16 @@ def call
self
end

def create_only
partner_request = ::Request.new(partner_id: partner.id,
organization_id: organization_id,
comments: comments,
partner_user_id: partner_user_id)
partner_request = populate_item_request(partner_request)
partner_request.assign_attributes(additional_attrs)
partner_request
end

private

attr_reader :partner_user_id, :comments, :item_requests_attributes, :additional_attrs
Expand Down
19 changes: 16 additions & 3 deletions app/views/partners/requests/new.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,17 @@
<div class="row">
<div class="col-md-12">
<!-- Default box -->
<div class="card">
<div class="card"
data-controller="confirmation"
data-confirmation-pre-check-path-value="<%= validate_partners_requests_path(format: :json) %>">
<div class="card-body">

<% if @errors.present? %>
<%= render partial: 'partners/requests/error' %>
<% end %>
<%= simple_form_for @partner_request, url: partners_requests_path(@partner_request),
html: {role: 'form', class: 'form-horizontal'}, method: :post, data: { controller: 'form-input' } do |form| %>
html: {role: 'form', class: 'form-horizontal'}, method: :post, data: { controller: 'form-input', confirmation_target: "form" } do |form| %>
<%= form.input :comments, label: "Comments:", as: :text, class: "form-control", wrapper: :input_group %>

<table class='table'>
Expand All @@ -56,9 +58,20 @@
</div>
<div class="card-footer">
<!-- TODO(chaserx): we should add some js to prevent submission if the items selected are the blank option or any item has an empty quantity -->
<%= form.submit("Submit Essentials Request", class: "btn btn-success") %> <%= link_to "Cancel Request", partners_requests_path, class: "btn btn-danger" %>
<%= form.submit("Submit Essentials Request", class: "btn btn-success", data: { action: "click->confirmation#openModal" }) %> <%= link_to "Cancel Request", partners_requests_path, class: "btn btn-danger" %>
</div>
<% end %>
<%# Confirmation modal: See confirmation_controller.js for how this gets displayed %>
<%# and app/controllers/partners/requests_controller.rb#validate for how it gets populated. %>
<div id="partnerRequestConfirmationModal"
class="modal confirm"
aria-labelledby="partnerRequestConfirmationModal"
aria-hidden="true"
tabindex="-1"
data-bs-backdrop="static"
data-confirmation-target="modal">
</div>
</div>
</div>
</div>
Expand Down
34 changes: 34 additions & 0 deletions app/views/partners/requests/validate.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Request Confirmation</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<table class="table">
<thead>
<tr>
<th>Item Name</th>
<th>Quantity</th>
</tr>
</thead>
<tbody>
<% @partner_request.item_requests.each do |line_item| %>
<tr>
<td><%= line_item.name %></td>
<td><%= line_item.quantity %></td>
</tr>
<% end %>
</tbody>
</table>

<div class="message fs-5">
<p>Please confirm that the above list is what you meant to request.</p>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" aria-label="No I need to make changes">No, I need to make changes</button>
<button type="button" class="btn btn-primary" data-action="confirmation#submitForm">Yes, it's correct</button>
</div>
</div>
</div>
33 changes: 33 additions & 0 deletions spec/models/request_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,39 @@
expect(subject.errors[:item_requests]).to include("should have unique item_ids")
end
end

context "when request is completely empty" do
let(:empty_request) { build(:request, comments: "", item_requests: []) }

it "is not valid" do
expect(empty_request).to_not be_valid
expect(empty_request.errors[:base]).to include("completely empty request")
end
end

context "when request has comments" do
let(:request_with_comments) { build(:request, comments: "Some comments", item_requests: []) }

it "is valid" do
expect(request_with_comments).to be_valid
end
end

context "when request has item_requests" do
let(:request_with_item_requests) { build(:request, comments: "", item_requests: [build(:item_request, item: item_one, quantity: 5)]) }

it "is valid" do
expect(request_with_item_requests).to be_valid
end
end

context "when request has both comments and item_requests" do
let(:request_with_both) { build(:request, comments: "Some comments", item_requests: [build(:item_request, item: item_two, quantity: 3)]) }

it "is valid" do
expect(request_with_both).to be_valid
end
end
end

describe "versioning" do
Expand Down
29 changes: 29 additions & 0 deletions spec/services/partners/request_create_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,33 @@
end
end
end

describe "#create_only" do
subject { described_class.new(**args).create_only }
let(:args) do
{
partner_user_id: partner_user.id,
comments: comments,
item_requests_attributes: item_requests_attributes
}
end
let(:partner_user) { partner.primary_user }
let(:partner) { create(:partner) }
let(:comments) { Faker::Lorem.paragraph }
let(:item) { FactoryBot.create(:item) }
let(:item_requests_attributes) do
[
ActionController::Parameters.new(
item_id: item.id,
quantity: 25
)
]
end

it "creates a partner request in memory only" do
expect(subject.id).to be_nil
expect(subject.item_requests.first.item.name).to eq(item.name)
expect(subject.item_requests.first.quantity).to eq("25")
end
end
end

0 comments on commit 8242bc9

Please sign in to comment.