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