Merge pull request #1261 from shlok007/resources

Ability to track resources
This commit is contained in:
Ana María Martínez Gómez 2017-02-09 10:45:51 +01:00 committed by GitHub
commit f42e4adc45
17 changed files with 265 additions and 2 deletions

View file

@ -0,0 +1,52 @@
module Admin
class ResourcesController < ApplicationController
load_and_authorize_resource :conference, find_by: :short_title
load_and_authorize_resource :resource, only: [:show, :edit, :update, :destroy]
def index; end
def edit; end
def new
@resource = @conference.resources.new
end
def create
@resource = @conference.resources.new(resource_params)
if @resource.save
redirect_to admin_conference_resources_path(conference_id: @conference.short_title),
notice: 'Resource successfully created.'
else
flash[:error] = "Creating resource failed: #{@resource.errors.full_messages.join('. ')}."
render :new
end
end
def update
if @resource.update_attributes(resource_params)
redirect_to admin_conference_resources_path(conference_id: @conference.short_title),
notice: 'Resource successfully updated.'
else
flash[:error] = "Resource update failed: #{@resource.errors.full_messages.join('. ')}."
render :edit
end
end
def destroy
if @resource.destroy
redirect_to admin_conference_resources_path(conference_id: @conference.short_title),
notice: 'Resource successfully destroyed.'
else
redirect_to admin_conference_resources_path(conference_id: @conference.short_title),
error: 'Resource was successfully destroyed.' \
"#{@resource.errors.full_messages.join('. ')}."
end
end
private
def resource_params
params.require(:resource).permit(:name, :description, :quantity, :used, :conference_id)
end
end
end

View file

@ -536,4 +536,8 @@ module ApplicationHelper
end
end
end
def quantity_left_of(resource)
"#{resource.quantity - resource.used}/#{resource.quantity}"
end
end

View file

@ -134,6 +134,7 @@ class Ability
# ids of all the conferences for which the user has the 'organizer' role
conf_ids_for_organizer = Conference.with_role(:organizer, user).pluck(:id)
can :manage, Resource, conference_id: conf_ids_for_organizer
can [:new, :create], Conference if user.has_role?(:organizer, :any)
can :manage, Conference, id: conf_ids_for_organizer
can :manage, Splashpage, conference_id: conf_ids_for_organizer
@ -187,6 +188,7 @@ class Ability
# ids of all the conferences for which the user has the 'cfp' role
conf_ids_for_cfp = Conference.with_role(:cfp, user).pluck(:id)
can [:index, :show, :update], Resource, conference_id: conf_ids_for_cfp
can :manage, Event, program: { conference_id: conf_ids_for_cfp }
can :manage, EventType, program: { conference_id: conf_ids_for_cfp }
can :manage, Track, program: { conference_id: conf_ids_for_cfp }
@ -223,6 +225,7 @@ class Ability
# ids of all the conferences for which the user has the 'info_desk' role
conf_ids_for_info_desk = Conference.with_role(:info_desk, user).pluck(:id)
can [:index, :show, :update], Resource, conference_id: conf_ids_for_info_desk
can :manage, Registration, conference_id: conf_ids_for_info_desk
can :manage, Question, conference_id: conf_ids_for_info_desk
can :manage, Question do |question|
@ -244,6 +247,7 @@ class Ability
# ids of all the conferences for which the user has the 'volunteers_coordinator' role
conf_ids_for_volunteers_coordinator = Conference.with_role(:volunteers_coordinator, user).pluck(:id)
can [:index, :show, :update], Resource, conference_id: conf_ids_for_volunteers_coordinator
can :manage, Vposition, conference_id: conf_ids_for_volunteers_coordinator
can :manage, Vday, conference_id: conf_ids_for_volunteers_coordinator

View file

@ -24,6 +24,7 @@ class Conference < ActiveRecord::Base
has_many :payments, dependent: :destroy
has_many :supporters, through: :ticket_purchases, source: :user
has_many :tickets, dependent: :destroy
has_many :resources, dependent: :destroy
has_many :lodgings, dependent: :destroy
has_many :registrations, dependent: :destroy

10
app/models/resource.rb Normal file
View file

@ -0,0 +1,10 @@
class Resource < ActiveRecord::Base
belongs_to :conference
validate :used_less_than_quantity
private
def used_less_than_quantity
errors.add(:used, 'can not be higher than total quantity') unless used <= quantity
end
end

View file

@ -0,0 +1,16 @@
.row
.col-md-12
.page-header
%h1
- if @resource.new_record?
New
Resource
.row
.col-md-8
= semantic_form_for(@resource, :url => (@resource.new_record? ? admin_conference_resources_path : admin_conference_resource_path(@conference.short_title, @resource))) do |f|
= f.input :name
= f.input :description, input_html: { rows: 5, data: { provide: "markdown-editable" } }
= f.input :used
= f.input :quantity
%p.text-right
= f.action :submit, as: :button, button_html: { class: 'btn btn-primary' }

View file

@ -0,0 +1,36 @@
.row
.col-md-12
.page-header
%h1 Resources
%p.text-muted
Manage resources in conference
- if @conference.resources.any?
.row
.col-md-12
%table.table.table-hover.datatable
%thead
%th Name
%th Left( Left/Total )
%th Used
%th Actions
%tbody
- @conference.resources.each do |resource|
%tr
%td
= link_to(admin_conference_resource_path(@conference.short_title, resource.id)) do
= resource.name
%td
= quantity_left_of(resource)
%td
= resource.used
%td
.btn-group
= link_to 'Edit', edit_admin_conference_resource_path(@conference.short_title, resource.id),
method: :get, class: 'btn btn-primary', disabled: !(can? :update, resource)
= link_to 'Delete', admin_conference_resource_path(@conference.short_title, resource.id),
method: :delete, class: 'btn btn-danger', disabled: !(can? :destroy, resource),
data: { confirm: "Do you really want to delete #{resource.name}?" }
.row
.col-md-12
= link_to 'Add Resource', new_admin_conference_resource_path, class: 'btn btn-success pull-right', disabled: !(can? :create, Resource.new(conference_id: @conference_id))

View file

@ -0,0 +1 @@
= render 'form'

View file

@ -0,0 +1,26 @@
.row
.col-md-12
%h3
= @resource.name
.btn-group.pull-right
= link_to 'Edit', edit_admin_conference_resource_path(@conference.short_title, @resource), class: 'btn btn-mini btn-primary'
%br
.row
.col-md-12
%table.table
%tr
%td.col-md-2
%b Description
%td
= @resource.description
%tr
%td
%b Total Quantity
%td
= @resource.quantity
%tr
%td
%b Quantity left
%td
= quantity_left_of(@resource)

View file

@ -139,3 +139,8 @@
= link_to(admin_conference_roles_path(@conference.short_title)) do
%span.fa.fa-group
Roles
- if can? :index, @conference.resources.new
%li
= link_to admin_conference_resources_path(@conference.short_title) do
%span.fa.fa-pencil-square
Resources

View file

@ -72,6 +72,7 @@ Osem::Application.routes.draw do
get 'reports' => 'events#reports'
end
resources :resources
resources :tickets
resources :sponsors, except: [:show]
resources :lodgings, except: [:show]

View file

@ -0,0 +1,11 @@
class CreateResourcesTable < ActiveRecord::Migration
def change
create_table :resources do |t|
t.string :name
t.text :description
t.integer :quantity
t.integer :used, default: 0
t.references :conference
end
end
end

View file

@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20160815140302) do
ActiveRecord::Schema.define(version: 20170129075434) do
create_table "ahoy_events", force: :cascade do |t|
t.uuid "visit_id", limit: 16
@ -344,6 +344,14 @@ ActiveRecord::Schema.define(version: 20160815140302) do
t.integer "vchoice_id"
end
create_table "resources", force: :cascade do |t|
t.string "name"
t.text "description"
t.integer "quantity"
t.integer "used", default: 0
t.integer "conference_id"
end
create_table "roles", force: :cascade do |t|
t.string "name"
t.datetime "created_at"

View file

@ -0,0 +1,8 @@
FactoryGirl.define do
factory :resource do
name { 'Resource' }
quantity { 10 }
used { 5 }
conference
end
end

View file

@ -0,0 +1,47 @@
require 'spec_helper'
feature Resource do
let!(:conference) { create(:conference) }
let!(:admin) { create(:admin) }
let!(:resource) { create(:resource, conference: conference) }
context 'as an admin' do
before(:each) do
sign_in admin
end
scenario 'create a new resource' do
visit admin_conference_resources_path(conference.short_title)
click_link 'Add Resource'
fill_in 'resource_name', with: 'shirts'
fill_in 'resource_description', with: 'what you love to wear!'
fill_in 'resource_quantity', with: 10
click_button 'Create Resource'
expect(Resource.count).to eq(2)
expect(flash).to eq('Resource successfully created.')
end
scenario 'edit an existing resource' do
visit admin_conference_resources_path(conference.short_title)
click_link('Edit', edit_admin_conference_resource_path(conference.short_title, resource.id))
fill_in 'resource_name', with: 'changed_name'
click_button 'Update Resource'
resource.reload
expect(flash).to eq('Resource successfully updated.')
expect(resource.name).to eq('changed_name')
end
scenario 'destroy a resource' do
visit admin_conference_resources_path(conference.short_title)
click_link('Delete', href: admin_conference_resource_path(conference.short_title, resource.id))
expect(flash).to eq('Resource successfully destroyed.')
end
end
end

View file

@ -29,7 +29,7 @@ describe 'User' do
let(:commercial_event_confirmed) { create(:commercial, commercialable: event_confirmed) }
let(:commercial_event_unconfirmed) { create(:commercial, commercialable: event_unconfirmed) }
let(:resource) { create(:resource, conference: my_conference)}
let(:registration) { create(:registration) }
let(:program_with_cfp) { create(:program, cfp: create(:cfp)) }
@ -235,6 +235,8 @@ describe 'User' do
it{ should be_able_to(:index, my_event.comment_threads.first) }
it{ should_not be_able_to(:index, other_event.comment_threads.first) }
it{ should be_able_to(:manage, resource)}
%w(organizer cfp info_desk volunteers_coordinator).each do |role|
it{ should be_able_to(:toggle_user, Role.find_by(name: role, resource: my_conference)) }
it{ should be_able_to(:edit, Role.find_by(name: role, resource: my_conference)) }
@ -304,6 +306,11 @@ describe 'User' do
it{ should be_able_to(:index, my_event.comment_threads.first) }
it{ should_not be_able_to(:index, other_event.comment_threads.first) }
it{ should_not be_able_to(:manage, resource)}
it{ should be_able_to(:index, resource)}
it{ should be_able_to(:show, resource)}
it{ should be_able_to(:update, resource)}
it_behaves_like 'user with any role'
it_behaves_like 'user with non-organizer role', 'cfp'
end
@ -366,6 +373,11 @@ describe 'User' do
it{ should_not be_able_to(:index, my_event.comment_threads.first) }
it{ should_not be_able_to(:index, other_event.comment_threads.first) }
it{ should_not be_able_to(:manage, resource)}
it{ should be_able_to(:index, resource)}
it{ should be_able_to(:show, resource)}
it{ should be_able_to(:update, resource)}
it_behaves_like 'user with any role'
it_behaves_like 'user with non-organizer role', 'info_desk'
end
@ -427,6 +439,12 @@ describe 'User' do
it{ should_not be_able_to(:manage, other_event.commercials.first) }
it{ should_not be_able_to(:index, my_event.comment_threads.first) }
it{ should_not be_able_to(:index, other_event.comment_threads.first) }
it{ should_not be_able_to(:manage, resource)}
it{ should be_able_to(:index, resource)}
it{ should be_able_to(:show, resource)}
it{ should be_able_to(:update, resource)}
it 'should be_able to :manage Vposition'
it 'should be_able to :manage Vday'

View file

@ -0,0 +1,15 @@
require 'spec_helper'
describe Resource do
let(:conference) { create(:conference) }
let(:resource) { create :resource }
it 'has a valid factory' do
expect(build(:resource)).to be_valid
end
it 'is not valid with used greater than quantity' do
resource.used = resource.quantity + 1
expect(resource.valid?).to eq false
end
end