mirror of
https://github.com/openSUSE/osem.git
synced 2026-08-13 19:54:02 +00:00
Merge pull request #1261 from shlok007/resources
Ability to track resources
This commit is contained in:
commit
f42e4adc45
17 changed files with 265 additions and 2 deletions
52
app/controllers/admin/resources_controller.rb
Normal file
52
app/controllers/admin/resources_controller.rb
Normal 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
|
||||
|
|
@ -536,4 +536,8 @@ module ApplicationHelper
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
def quantity_left_of(resource)
|
||||
"#{resource.quantity - resource.used}/#{resource.quantity}"
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
10
app/models/resource.rb
Normal 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
|
||||
16
app/views/admin/resources/_form.html.haml
Normal file
16
app/views/admin/resources/_form.html.haml
Normal 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' }
|
||||
36
app/views/admin/resources/index.html.haml
Normal file
36
app/views/admin/resources/index.html.haml
Normal 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))
|
||||
|
||||
1
app/views/admin/resources/new.html.haml
Normal file
1
app/views/admin/resources/new.html.haml
Normal file
|
|
@ -0,0 +1 @@
|
|||
= render 'form'
|
||||
26
app/views/admin/resources/show.html.haml
Normal file
26
app/views/admin/resources/show.html.haml
Normal 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)
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
11
db/migrate/20170129075434_create_resources_table.rb
Normal file
11
db/migrate/20170129075434_create_resources_table.rb
Normal 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
|
||||
10
db/schema.rb
10
db/schema.rb
|
|
@ -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"
|
||||
|
|
|
|||
8
spec/factories/resource.rb
Normal file
8
spec/factories/resource.rb
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
FactoryGirl.define do
|
||||
factory :resource do
|
||||
name { 'Resource' }
|
||||
quantity { 10 }
|
||||
used { 5 }
|
||||
conference
|
||||
end
|
||||
end
|
||||
47
spec/features/resource_spec.rb
Normal file
47
spec/features/resource_spec.rb
Normal 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
|
||||
|
|
@ -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'
|
||||
|
||||
|
|
|
|||
15
spec/models/resource_spec.rb
Normal file
15
spec/models/resource_spec.rb
Normal 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue