Move #give_time from orgs to transfers controller

This duplicates the OrganizationsController#give_time to
TransferController#new as it should be by Rails conventions. We aim to
stick to REST conventions of the Transfer resource instead of having
custom actions on users and organizations controllers.
This commit is contained in:
Pau Perez
2017-08-16 19:04:26 +02:00
parent 72b7bad68f
commit 9a1d6b098a
4 changed files with 256 additions and 62 deletions

View File

@ -15,20 +15,32 @@ class TransfersController < ApplicationController
end
def new
@user = scoped_users.find(params[:id])
@destination = @user
.members
.find_by(organization: current_organization)
.account
.id
@source = find_transfer_source
@offer = find_transfer_offer
@transfer = Transfer.new(
source: @source,
destination: @destination,
post: @offer
)
@sources = find_transfer_sources_for_admin
if for_organization?
load_resource
@source = find_transfer_source
@offer = find_transfer_offer
@destination = @organization.account.id
@transfer = Transfer.new(source: @source, destination: @destination)
@sources = find_transfer_sources_for_admin
render :new_organization
else
@user = scoped_users.find(params[:id])
@destination = @user
.members
.find_by(organization: current_organization)
.account
.id
@source = find_transfer_source
@offer = find_transfer_offer
@transfer = Transfer.new(
source: @source,
destination: @destination,
post: @offer
)
@sources = find_transfer_sources_for_admin
end
end
def delete_reason
@ -42,6 +54,18 @@ class TransfersController < ApplicationController
private
def for_organization?
params.key?('organization')
end
def load_resource
if params[:id]
@organization = Organization.find(params[:id])
else
@organizations = Organization.all
end
end
def find_transfer_sources_for_admin
return unless admin?
[current_organization.account] +
@ -54,8 +78,13 @@ class TransfersController < ApplicationController
end
def find_transfer_source
current_user.members.
find_by(organization: current_organization).account.id
if for_organization?
current_user.members.
find_by(organization: @organization).account.id
else
current_user.members.
find_by(organization: current_organization).account.id
end
end
def scoped_users

View File

@ -0,0 +1,66 @@
<h1>
<small>
<%= t ".give_time" %>
</small>
<%= link_to @user.member(current_organization).display_name_with_uid, user_path(@user) %>
</h1>
<% if @offer %>
<h3>
<%= @offer %>
</h3>
<% end %>
<%= simple_form_for @transfer do |f| %>
<div class="form-inputs">
<%= f.input :hours,
as: :integer,
input_html: {
min: 0,
max: 20,
"data-rule-either-hours-minutes-informed" => "true",
"data-rule-range" => "[0,20]"
} %>
<%= f.input :minutes,
as: :integer,
input_html: {
min: 0,
max: 59,
step: 15,
"data-rule-either-hours-minutes-informed" => "true",
"data-rule-range" => "[0,59]"
} %>
<%= f.input :amount, as: :hidden %>
<%= f.input :reason %>
<%= f.input :destination, as: :hidden %>
<% if admin? %>
<div class="form-group">
<%= f.label :source %>
<%= f.select :source,
options_for_select(
@sources.sort_by { |source| [source.accountable_type, source.accountable.try(:member_uid)] }
.map { |a| ["#{a.accountable_type == "Member" ? a.accountable.member_uid : ""} #{a.accountable_type} #{a.accountable.to_s}", a.id] },
selected: current_user.member(current_organization).account.id
),
{},
id: "select2-time",
class: "form-control" %>
</div>
<% end %>
<% if @offer %>
<%= f.input :post, readonly: true %>
<%= f.input :post_id, as: :hidden %>
<% else %>
<%= f.input :post_id, collection: @user.member(current_organization).offers.active %>
<% end %>
</div>
<div class="form-actions">
<%= f.button :submit, class: "btn btn-default", style: "margin-bottom: 20px;" %>
</div>
<% end %>
<script type="text/javascript">
$("#select2-time").select2({
formatNoMatches: function() {
return "<%= j t('application.tips.user_not_found') %>";
}
});
</script>

View File

@ -0,0 +1,63 @@
<h1>
<small><%= t '.give_time' %></small>
<%= link_to @organization, organization_path(@organization) %>
</h1>
<% if @offer %>
<h3>
<%= @offer %>
</h3>
<% end %>
<%= simple_form_for @transfer do |f| %>
<div class="form-inputs">
<%= f.input :hours,
as: :integer,
input_html: {
min: 0,
max: 20,
'data-rule-either-hours-minutes-informed' => 'true',
'data-rule-range' => '[0,20]'
} %>
<%= f.input :minutes,
as: :integer,
input_html: {
min: 0,
max: 59,
step: 15,
'data-rule-either-hours-minutes-informed' => 'true',
'data-rule-range' => '[0,59]'
} %>
<%= f.input :amount, as: :hidden %>
<%= f.input :reason %>
<%= f.input :destination, as: :hidden %>
<% if admin? %>
<div class="form-group">
<%= f.label :source %>
<%# TODO: refactor. it's very complex for a view. %>
<%= f.select :source,
options_for_select(
@sources.sort_by { |source| [source.accountable_type, source.accountable_id] }
.map { |a| ["#{a.accountable_type == 'Member' ? a.accountable.member_uid : a.accountable_id} #{a.accountable_type} #{a.accountable.to_s}", a.id] },
selected: current_user.member(current_organization).account.id
),
{},
id: 'select2-time',
class: 'form-control' %>
</div>
<% end %>
<% if @offer %>
<%= f.input :post, as: :hidden %>
<% end %>
</div>
<div class="form-actions">
<%= f.button :submit,
class: 'btn btn-default',
style: 'margin-bottom: 20px;' %>
</div>
<% end %>
<script>
$("#select2-time").select2({
formatNoMatches: function () {
return "<%= j t('application.tips.user_not_found') %>";
}
});
</script>

View File

@ -12,68 +12,104 @@ describe TransfersController do
describe '#new' do
let(:user) { member_giver.user }
let(:params) { { id: user.id } }
before { login(user) }
it 'renders the :new template' do
expect(get :new, params).to render_template(:new)
end
context 'when the destination is a user account' do
let(:params) { { id: user.id } }
it 'finds the user' do
get :new, params
expect(assigns(:user)).to eq(user)
end
it 'renders the :new template' do
expect(get :new, params).to render_template(:new)
end
it 'finds the destination account' do
get :new, params
account = user.members.find_by(organization: user.organizations.first).account
expect(assigns(:destination)).to eq(account.id)
end
it 'finds the transfer source' do
get :new, params
source = user.members.find_by(organization: user.organizations.first).account.id
expect(assigns(:source)).to eq(source)
end
context 'when the offer is specified' do
let(:offer) { Fabricate(:offer, organization: user.organizations.first) }
before { params.merge!(offer: offer.id) }
it 'finds the transfer offer' do
it 'finds the user' do
get :new, params
offer = user.organizations.first.offers.find(params[:offer])
expect(assigns(:user)).to eq(user)
end
expect(assigns(:offer)).to eq(offer)
it 'finds the destination account' do
get :new, params
account = user.members.find_by(organization: user.organizations.first).account
expect(assigns(:destination)).to eq(account.id)
end
it 'finds the transfer source' do
get :new, params
source = user.members.find_by(organization: user.organizations.first).account.id
expect(assigns(:source)).to eq(source)
end
context 'when the offer is specified' do
let(:offer) { Fabricate(:offer, organization: user.organizations.first) }
it 'finds the transfer offer' do
get :new, params.merge(offer: offer.id)
expect(assigns(:offer)).to eq(offer)
end
end
context 'when the offer is not specified' do
it 'does not find any offer' do
get :new, params
expect(assigns(:offer)).to be_nil
end
end
context 'when the user is admin of the current organization' do
let(:user) { member_admin.user }
it 'finds all accounts in the organization as sources' do
get :new, params
expect(assigns(:sources)).to contain_exactly(
test_organization.account, member_admin.account
)
end
end
context 'when the user is not admin of the current organization' do
it 'does not assign :sources' do
get :new, params
expect(assigns(:sources)).to be_nil
end
end
end
context 'when the offer is not specified' do
it 'does not find any offer' do
get :new, params
expect(assigns(:offer)).to be_nil
context 'when the destination is an organization account' do
let(:params) { { id: test_organization.id, organization: true } }
it 'renders the :new template' do
expect(get :new, params).to render_template(:new_organization)
end
end
context 'when the user is admin of the current organization' do
let(:user) { member_admin.user }
it 'finds all accounts in the organization as sources' do
it 'finds the destination account' do
get :new, params
expect(assigns(:sources)).to contain_exactly(
test_organization.account, member_admin.account
)
expect(assigns(:destination)).to eq(test_organization.account.id)
end
end
context 'when the user is not admin of the current organization' do
it 'does not assign :sources' do
context 'when the user is the admin of the current organization' do
let(:user) { member_admin.user }
it 'renders the page successfully' do
expect(get :new, params).to be_ok
end
end
it 'finds the transfer source' do
get :new, params
expect(assigns(:sources)).to be_nil
source = user.members.find_by(organization: test_organization).account.id
expect(assigns(:source)).to eq(source)
end
context 'when an offer is specified' do
let(:offer) { Fabricate(:offer, organization: test_organization) }
it 'finds the transfer offer' do
get :new, params.merge(offer: offer.id)
expect(assigns(:offer)).to eq(offer)
end
end
end
end