From 1d578aa3ea55dec29a35ba95ea39fe45e1deb6fb Mon Sep 17 00:00:00 2001 From: Michael Kohl Date: Mon, 11 May 2020 21:49:05 +0700 Subject: [PATCH] [deploy] Add org credit management to org mod page (#7761) * Add org credit management to org mod page * Fix typo --- .../internal/organizations_controller.rb | 31 ++++++++++++++++++- app/helpers/organization_helper.rb | 8 +++++ .../internal/organizations/show.html.erb | 22 +++++++++++++ app/views/internal/users/_credits.erb | 19 +++++++----- config/routes.rb | 6 +++- spec/helpers/organization_helper_spec.rb | 13 ++++++++ spec/requests/internal/organizations_spec.rb | 23 ++++++++++++++ .../admin_manages_organizations_spec.rb | 27 +++++++++++----- 8 files changed, 132 insertions(+), 17 deletions(-) create mode 100644 app/helpers/organization_helper.rb create mode 100644 spec/helpers/organization_helper_spec.rb diff --git a/app/controllers/internal/organizations_controller.rb b/app/controllers/internal/organizations_controller.rb index 91de90e15..2525afd17 100644 --- a/app/controllers/internal/organizations_controller.rb +++ b/app/controllers/internal/organizations_controller.rb @@ -1,8 +1,13 @@ class Internal::OrganizationsController < Internal::ApplicationController layout "internal" + CREDIT_ACTIONS = { + add: :add_to_org, + remove: :remove_from_org + }.with_indifferent_access.freeze + def index - @organizations = Organization.order("name DESC").page(params[:page]).per(50) + @organizations = Organization.order(name: :desc).page(params[:page]).per(50) return if params[:search].blank? @@ -15,4 +20,28 @@ class Internal::OrganizationsController < Internal::ApplicationController def show @organization = Organization.find(params[:id]) end + + def update_org_credits + org = Organization.find(params[:id]) + amount = params[:credits].to_i + update_action = CREDIT_ACTIONS.fetch(params[:credit_action]) + + Credit.public_send(update_action, org, amount) + add_note(org) + + flash[:notice] = "Sucessfully updated credits" + redirect_to internal_organization_path(org) + end + + private + + def add_note(org) + Note.create( + author_id: current_user.id, + noteable_id: org.id, + noteable_type: "Organization", + reason: "misc_note", + content: params[:note], + ) + end end diff --git a/app/helpers/organization_helper.rb b/app/helpers/organization_helper.rb new file mode 100644 index 000000000..d046f7677 --- /dev/null +++ b/app/helpers/organization_helper.rb @@ -0,0 +1,8 @@ +module OrganizationHelper + def orgs_with_credits(organizations) + options = organizations.map do |org| + ["#{org.name} (#{org.unspent_credits_count})", org.id] + end + options_for_select(options) + end +end diff --git a/app/views/internal/organizations/show.html.erb b/app/views/internal/organizations/show.html.erb index fc6c6d0e3..bea7065dc 100644 --- a/app/views/internal/organizations/show.html.erb +++ b/app/views/internal/organizations/show.html.erb @@ -30,6 +30,28 @@ <% end %> +
+ <% current_credits = @organization.unspent_credits_count %> +

Credits (currrent: <%= current_credits %>)

+ <%= form_tag update_org_credits_internal_organization_path(@organization), method: :patch, class: "form-inline justify-content-between mb-2" do %> +
+ <%= hidden_field_tag :credit_action, :add %> + <%= number_field_tag :credits, nil, in: 1...100000, required: true, class: "form-control mr-3", size: 5 %> + <%= text_field_tag :note, "", placeholder: "Why are you adding these credits?", size: 50, required: true, class: "form-control mr-3" %> +
+ <%= submit_tag "Add Org Credits", class: "btn btn-primary" %> + <% end %> + <% if current_credits.positive? %> + <%= form_tag update_org_credits_internal_organization_path(@organization), method: :patch, class: "form-inline justify-content-between mb-2" do %> +
+ <%= hidden_field_tag :credit_action, :remove %> + <%= number_field_tag :credits, nil, in: 1..current_credits, required: true, class: "form-control mr-3", size: 5 %> + <%= text_field_tag :note, "", placeholder: "Why are you removing these credits?", size: 50, required: true, class: "form-control mr-3" %> +
+ <%= submit_tag "Remove Org Credits", class: "btn btn-danger" %> + <% end %> + <% end %> +
<%= render "activity" %> diff --git a/app/views/internal/users/_credits.erb b/app/views/internal/users/_credits.erb index aa535e160..38394c905 100644 --- a/app/views/internal/users/_credits.erb +++ b/app/views/internal/users/_credits.erb @@ -3,41 +3,46 @@

Credits


<%= @user.username %>

-

Available User Credits: <%= @user.unspent_credits_count %>

+ <% current_credits = @user.unspent_credits_count %> +

Available User Credits: <%= current_credits %>

<%= form_with scope: :user, url: internal_user_path(@user), method: :patch, local: true, html: { class: "form-inline justify-content-between mb-2" } do |f| %>
- <%= f.text_field :add_credits, placeholder: "#", size: 5, class: "form-control mr-3" %> + <%= f.number_field :add_credits, in: 1...10000, required: true, class: "form-control mr-3", size: 5 %> <%= f.text_field :new_note, placeholder: "Why are you adding these credits?", size: 50, required: true, class: "form-control" %>
<%= f.submit "Add Credits", class: "btn btn-primary" %> <% end %> + <% if current_credits.positive? %> <%= form_with scope: :user, url: internal_user_path(@user), method: :patch, local: true, html: { class: "form-inline justify-content-between mb-2" } do |f| %>
- <%= f.text_field :remove_credits, placeholder: "#", size: 5, class: "form-control mr-3" %> + <%= f.number_field :remove_credits, in: 1..current_credits, required: true, class: "form-control mr-3", size: 5 %> <%= f.text_field :new_note, placeholder: "Why are you removing these credits?", size: 50, required: true, class: "form-control" %>
<%= f.submit "Remove Credits", class: "btn btn-danger" %> <% end %> + <% end %>
+ <% if @organizations.present? %>

Organizations

<%= form_with scope: :user, url: internal_user_path(@user), method: :patch, local: true, html: { class: "form-inline justify-content-between mb-2" } do |f| %>
- <%= f.text_field :add_org_credits, placeholder: "#", size: 5, class: "form-control mr-3" %> + <%= f.number_field :add_org_credits, in: 1...10000, required: true, class: "form-control mr-3", size: 5 %> <%= f.text_field :new_note, placeholder: "Why are you adding these credits?", size: 50, required: true, class: "form-control mr-3" %> - <%= f.collection_select :organization_id, @organizations, :id, :name, {}, { class: 'form-control' } %> + <%= f.select :organization_id, orgs_with_credits(@organizations), {}, { class: 'form-control' } %>
<%= f.submit "Add Org Credits", class: "btn btn-primary" %> <% end %> <%= form_with scope: :user, url: internal_user_path(@user), method: :patch, local: true, html: { class: "form-inline justify-content-between mb-2" } do |f| %>
- <%= f.text_field :remove_org_credits, placeholder: "#", size: 5, class: "form-control mr-3" %> + <%= f.number_field :remove_org_credits, in: 1...10000, required: true, class: "form-control mr-3", size: 5 %> <%= f.text_field :new_note, placeholder: "Why are you removing these credits?", size: 50, required: true, class: "form-control mr-3" %> - <%= f.collection_select :organization_id, @organizations, :id, :name, {}, { class: 'form-control' } %> + <%= f.select :organization_id, orgs_with_credits(@organizations), {}, { class: 'form-control' } %>
<%= f.submit "Remove Org Credits", class: "btn btn-danger" %> <% end %>
+ <% end %> diff --git a/config/routes.rb b/config/routes.rb index 10ab28f16..62b23b9ef 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -89,7 +89,11 @@ Rails.application.routes.draw do end end resources :organization_memberships, only: %i[update destroy create] - resources :organizations, only: %i[index show] + resources :organizations, only: %i[index show] do + member do + patch "update_org_credits" + end + end resources :sponsorships, only: %i[index edit update destroy] resources :welcome, only: %i[index create] resources :growth, only: %i[index] diff --git a/spec/helpers/organization_helper_spec.rb b/spec/helpers/organization_helper_spec.rb new file mode 100644 index 000000000..b080607d4 --- /dev/null +++ b/spec/helpers/organization_helper_spec.rb @@ -0,0 +1,13 @@ +require "rails_helper" + +describe OrganizationHelper, type: :helper do + it "display the correct options" do + org1 = create(:organization) + org2 = create(:organization) + allow(org1).to receive(:unspent_credits_count).and_return(1) + + options = helper.orgs_with_credits([org1, org2]) + expect(options).to include("#{org1.name} (1)") + expect(options).to include("#{org2.name} (0)") + end +end diff --git a/spec/requests/internal/organizations_spec.rb b/spec/requests/internal/organizations_spec.rb index 550afec57..7f76286f2 100644 --- a/spec/requests/internal/organizations_spec.rb +++ b/spec/requests/internal/organizations_spec.rb @@ -31,4 +31,27 @@ RSpec.describe "internal/organizations", type: :request do expect(response.body).to include(CGI.escapeHTML(organization.name)) end end + + describe "PATCH /internal" do + let(:organization) { create(:organization) } + + it "adds credits to an organization" do + params = { credits: 1, credit_action: :add } + + expect do + patch update_org_credits_internal_organization_path(organization), + params: params + end.to change { organization.reload.unspent_credits_count }.by(1) + end + + it "removes credits to an organization" do + Credit.add_to_org(organization, 1) + params = { credits: 1, credit_action: :remove } + + expect do + patch update_org_credits_internal_organization_path(organization), + params: params + end.to change { organization.reload.unspent_credits_count }.by(-1) + end + end end diff --git a/spec/system/internal/admin_manages_organizations_spec.rb b/spec/system/internal/admin_manages_organizations_spec.rb index 706f35bc6..89ff2d5e7 100644 --- a/spec/system/internal/admin_manages_organizations_spec.rb +++ b/spec/system/internal/admin_manages_organizations_spec.rb @@ -4,15 +4,26 @@ RSpec.describe "Admin manages organizations", type: :system do let(:admin) { create(:user, :super_admin) } let(:organization) { create(:organization) } - before do - create_list :organization, 5 - sign_in admin - visit "/internal/organizations" + before { sign_in admin } + + context "when searching for organizations" do + it "searches for organizations" do + create_list :organization, 5 + visit internal_organizations_path + + fill_in "search", with: organization.name.to_s + click_on "Search" + + expect(page.body).to have_link(organization.name) + end end - it "searches for organizations" do - fill_in "search", with: organization.name.to_s - click_on "Search" - expect(page.body).to have_link(organization.name) + context "when managing credits for a single organization" do + before { visit internal_organization_path(organization) } + + it "does not show the remove form when there are no credits" do + expect(page).to have_button("Add Org Credits") + #expect(page).to have_no_button("Remove Org Credits") + end end end