voluntary_recruiting 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +1 -0
  4. data/Rakefile +26 -0
  5. data/app/controllers/candidatures_controller.rb +84 -0
  6. data/app/controllers/vacancies_controller.rb +88 -0
  7. data/app/controllers/workflow/candidatures_controller.rb +20 -0
  8. data/app/controllers/workflow/vacancies_controller.rb +17 -0
  9. data/app/models/candidature.rb +38 -0
  10. data/app/models/product/recruiting.rb +2 -0
  11. data/app/models/state_machines/candidature.rb +64 -0
  12. data/app/models/state_machines/vacancy.rb +49 -0
  13. data/app/models/vacancy.rb +43 -0
  14. data/app/views/candidatures/_form.html.erb +13 -0
  15. data/app/views/candidatures/edit.html.erb +3 -0
  16. data/app/views/candidatures/index.html.erb +11 -0
  17. data/app/views/candidatures/new.html.erb +3 -0
  18. data/app/views/candidatures/show.html.erb +18 -0
  19. data/app/views/vacancies/_form.html.erb +15 -0
  20. data/app/views/vacancies/edit.html.erb +3 -0
  21. data/app/views/vacancies/index.html.erb +7 -0
  22. data/app/views/vacancies/new.html.erb +3 -0
  23. data/app/views/vacancies/show.html.erb +15 -0
  24. data/app/views/workflow/project_owner/_candidatures.html.erb +32 -0
  25. data/app/views/workflow/project_owner/_vacancies.html.erb +27 -0
  26. data/config/locales/general/en.yml +17 -0
  27. data/config/locales/resources/candidature/en.yml +18 -0
  28. data/config/locales/resources/vacancy/en.yml +33 -0
  29. data/config/routes.rb +67 -0
  30. data/db/migrate/20150711124651_add_recruiting.rb +60 -0
  31. data/lib/tasks/voluntary_recruiting_tasks.rake +4 -0
  32. data/lib/voluntary_recruiting.rb +13 -0
  33. data/lib/voluntary_recruiting/ability.rb +17 -0
  34. data/lib/voluntary_recruiting/concerns/model/project/recruitable.rb +15 -0
  35. data/lib/voluntary_recruiting/concerns/model/project_user/recruitable.rb +19 -0
  36. data/lib/voluntary_recruiting/concerns/model/user/recruitable.rb +17 -0
  37. data/lib/voluntary_recruiting/controller/project_owner_controller.rb +26 -0
  38. data/lib/voluntary_recruiting/engine.rb +22 -0
  39. data/lib/voluntary_recruiting/navigation.rb +106 -0
  40. data/lib/voluntary_recruiting/version.rb +3 -0
  41. metadata +336 -0
@@ -0,0 +1,13 @@
1
+ <%= simple_form_for(@candidature) do |f| %>
2
+ <%= render partial: 'shared/form/error_messages', locals: { resource: @candidature } %>
3
+
4
+ <div class="form-inputs">
5
+ <%= @candidature.vacancy ? f.hidden_field(:vacancy_id) : f.association(:vacancy) %>
6
+ <%= f.input :name %>
7
+ <%= f.input :text, input_html: {style: 'width: 500px; height:300px;'} %>
8
+ </div>
9
+
10
+ <div class="form-actions">
11
+ <%= f.button :submit %>
12
+ </div>
13
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <h3><%= t('candidatures.edit.title') %></h3>
2
+
3
+ <%= render 'form' %>
@@ -0,0 +1,11 @@
1
+ <% columns = { 'name' => 'resource.name', 'resource_id' => ''} %>
2
+ <% columns['vacancy_id'] = '' unless @vacancy %>
3
+ <% columns['project_id'] = 'vacancy.project' unless @vacancy %>
4
+
5
+ <%= form_tag update_multiple_candidatures_path, method: :post do %>
6
+ <%= render partial: "shared/collection/#{@vacancy ? 'list' : 'table'}", locals: {
7
+ type: 'candidatures', collection: @candidatures, columns: columns, content_column: 'text'
8
+ } %>
9
+ <% end %>
10
+
11
+ <%= link_to t('candidatures.new.title'), new_vacancy_candidature_path(@vacancy) if @vacancy %>
@@ -0,0 +1,3 @@
1
+ <h3><%= t('candidatures.new.title') %></h3>
2
+
3
+ <%= render 'form' %>
@@ -0,0 +1,18 @@
1
+ <h3>
2
+ <a name="top">&nbsp;</a>
3
+ <% if @candidature.name.present? %>
4
+ <%= @candidature.name %>
5
+ <% else %>
6
+ No Name
7
+ <% end %>
8
+ </h3>
9
+
10
+ <dl class="dl-horizontal">
11
+ <%= show_associations :project, :vacancy, :resource %>
12
+ <%= show_attribute :state %>
13
+ <%= show_actions %>
14
+ </dl>
15
+
16
+ <%= markdown @candidature.text %>
17
+
18
+ <%= render 'shared/comments', comment: @candidature.comments.new %>
@@ -0,0 +1,15 @@
1
+ <%= simple_form_for(@vacancy, html: {class: 'form-horizontal'}) do |f| %>
2
+ <%= render partial: 'shared/form/error_messages', locals: { resource: @vacancy } %>
3
+
4
+ <div class="form-inputs">
5
+ <%= @vacancy.project ? f.hidden_field(:project_id) : f.association(:project) %>
6
+
7
+ <%= f.input :name %>
8
+ <%= f.input :text, input_html: {style: 'width: 500px; height:300px;'} %>
9
+ <%= f.input :limit %>
10
+ </div>
11
+
12
+ <div class="form-actions">
13
+ <%= f.button :submit %>
14
+ </div>
15
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <h3><%= t('vacancies.edit.title') %></h3>
2
+
3
+ <%= render 'form' %>
@@ -0,0 +1,7 @@
1
+ <%= form_tag update_multiple_candidatures_path, method: :post do %>
2
+ <%= render partial: "shared/collection/#{@project ? 'list' : 'table'}", locals: {
3
+ type: 'vacancies', collection: @vacancies, columns: ['name', 'project_id'], content_column: 'text'
4
+ } %>
5
+ <% end %>
6
+
7
+ <%= link_to t('vacancies.new.title'), new_project_vacancy_path(@project) if @project %>
@@ -0,0 +1,3 @@
1
+ <h3><%= t('vacancies.new.title') %></h3>
2
+
3
+ <%= render 'form' %>
@@ -0,0 +1,15 @@
1
+ <h3>
2
+ <a id="top" name="top"></a>
3
+ <%= @vacancy.name %>
4
+ </h3>
5
+
6
+ <dl class="dl-horizontal">
7
+ <%= show_associations :project %>
8
+ <%= show_attribute :limit, value: "#{@vacancy.candidatures_left} / #{@vacancy.limit}" %>
9
+ <%= show_attribute :state %>
10
+ <%= show_actions %>
11
+ </dl>
12
+
13
+ <%= markdown @vacancy.text %>
14
+
15
+ <%= render 'shared/comments', comment: @vacancy.comments.new %>
@@ -0,0 +1,32 @@
1
+ <div class="tabs">
2
+ <ul>
3
+ <% Candidature::STATES.each do |state| %>
4
+ <li>
5
+ <a href="#<%= state %>_candidatures">
6
+ <%= I18n.t("candidatures.show.states.#{state}") %>
7
+ <% if @candidatures[state].length == 5 %>
8
+ (<%= @candidatures[state].length %>+)
9
+ <% elsif @candidatures[state].length > 0 %>
10
+ (<%= @candidatures[state].length %>)
11
+ <% end %>
12
+ </a>
13
+ </li>
14
+ <% end %>
15
+ </ul>
16
+ <% Candidature::STATES.each do |state| %>
17
+ <div id="<%= state %>_candidatures">
18
+ <%= render partial: 'shared/collection/table', locals: {
19
+ type: 'candidatures', collection: @candidatures[state],
20
+ columns: {
21
+ 'project_id' => 'vacancy.project', 'vacancy_id' => '', 'name' => 'user.name',
22
+ 'resource_id' => ''
23
+ },
24
+ options: {show_title: false, append_new_link: false }
25
+ } %>
26
+
27
+ <% if @candidatures[state].length == 5 %>
28
+ <p><%= link_to t('general.more'), eval("#{state}_workflow_candidatures_path") %></p>
29
+ <% end %>
30
+ </div>
31
+ <% end %>
32
+ </div>
@@ -0,0 +1,27 @@
1
+ <div class="tabs">
2
+ <ul>
3
+ <% Vacancy::STATES.each do |state| %>
4
+ <li>
5
+ <a href="#<%= state %>_vacancies">
6
+ <%= I18n.t("vacancies.show.states.#{state}") %>
7
+ <% if @vacancies[state].length == 5 %>
8
+ (<%= @vacancies[state].length %>+)
9
+ <% elsif @vacancies[state].length > 0 %>
10
+ (<%= @vacancies[state].length %>)
11
+ <% end %>
12
+ </a>
13
+ </li>
14
+ <% end %>
15
+ </ul>
16
+ <% Vacancy::STATES.each do |state| %>
17
+ <div id="<%= state %>_vacancies">
18
+ <%= render partial: 'shared/collection/table', locals: {
19
+ type: 'vacancies', collection: @vacancies[state], columns: ['name', 'project_id'],
20
+ options: {show_title: false, append_new_link: false }
21
+ } %>
22
+ <% if @vacancies[state].length == 5 %>
23
+ <p><%= link_to t('general.more'), eval("#{state}_workflow_vacancies_path") if @vacancies[state].length > 0 %></p>
24
+ <% end %>
25
+ </div>
26
+ <% end %>
27
+ </div>
@@ -0,0 +1,17 @@
1
+ en:
2
+ attributes:
3
+ vacancy_id: Vacancy
4
+
5
+ activerecord:
6
+ models:
7
+ candidature: Candidature
8
+ vacancy: Vacancy
9
+
10
+ attributes:
11
+ vacancy:
12
+ name: Name
13
+ limit: Limit
14
+
15
+ home:
16
+ index:
17
+ last_vacancies: Last vacancies
@@ -0,0 +1,18 @@
1
+ en:
2
+ candidatures:
3
+ index:
4
+ title: Candidatures
5
+ empty_collection: No candidatures available.
6
+ new:
7
+ title: New Candidature
8
+ edit:
9
+ title: Edit Candidature
10
+ show:
11
+ states:
12
+ new: New
13
+ accepted: Accepted
14
+ denied: Denied
15
+ events:
16
+ accept: Accept
17
+ deny: Deny
18
+ quit: Quit
@@ -0,0 +1,33 @@
1
+ en:
2
+ vacancies:
3
+ index:
4
+ title: Vacancies
5
+ empty_collection: No vacancies available.
6
+ new:
7
+ title: New Vacancy
8
+ edit:
9
+ title: Edit Vacancy
10
+ show:
11
+ states:
12
+ open: Open
13
+ recommended: Recommended
14
+ denied: Denied
15
+ closed: Closed
16
+ events:
17
+ recommend: Recommend
18
+ accept_recommendation: Accept recommendation
19
+ deny_recommendation: Deny recommendation
20
+ close: Close
21
+ reopen: Reopen
22
+
23
+ activerecord:
24
+ attributes:
25
+ vacancy:
26
+ limit: Limit
27
+
28
+ errors:
29
+ models:
30
+ vacancy:
31
+ attributes:
32
+ limit:
33
+ reached: Limit of candidatures already reached
data/config/routes.rb ADDED
@@ -0,0 +1,67 @@
1
+ Rails.application.routes.draw do
2
+ resources :projects do
3
+ resources :vacancies, only: [:index, :new]
4
+ end
5
+
6
+ get 'users/:user_id/candidatures', to: 'candidatures#index', as: 'user_candidatures'
7
+
8
+ resources :vacancies do
9
+ resources :candidatures, only: [:index, :new]
10
+ resources :comments, only: [:index, :new]
11
+
12
+ collection do
13
+ put :update_multiple
14
+ get :autocomplete
15
+ end
16
+
17
+ member do
18
+ put :recommend
19
+ put :accept_recommendation
20
+ put :deny_recommendation
21
+ put :close
22
+ put :reopen
23
+ end
24
+ end
25
+
26
+ resources :candidatures do
27
+ resources :comments, only: [:index, :new]
28
+
29
+ collection do
30
+ put :update_multiple
31
+ get :autocomplete
32
+ end
33
+
34
+ member do
35
+ get :accept
36
+ get :deny
37
+ get :quit
38
+ end
39
+ end
40
+
41
+ namespace 'workflow' do
42
+ resources :vacancies, controller: 'vacancies', only: :index do
43
+ collection do
44
+ get '/' => 'vacancies#open', as: :open
45
+
46
+ get :autocomplete
47
+
48
+ get :open
49
+ get :recommended
50
+ get :denied
51
+ get :closed
52
+ end
53
+ end
54
+
55
+ resources :candidatures, controller: 'candidatures', only: :index do
56
+ collection do
57
+ get '/' => 'candidatures#new', as: :new
58
+
59
+ get :autocomplete
60
+
61
+ get :new
62
+ get :accepted
63
+ get :denied
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,60 @@
1
+ class AddRecruiting < ActiveRecord::Migration
2
+ def up
3
+ if product = Product.where(name: 'Recruiting').first
4
+ else
5
+ Product.create(name: 'Recruiting', text: 'Dummy')
6
+ end
7
+
8
+ unless ActiveRecord::Base.connection.table_exists? 'vacancies'
9
+ create_table "vacancies", force: true do |t|
10
+ t.string "type"
11
+ t.integer "project_id"
12
+ t.integer "offeror_id"
13
+ t.integer "author_id"
14
+ t.integer "project_user_id"
15
+ t.string "name"
16
+ t.string "slug"
17
+ t.text "text"
18
+ t.integer "limit", default: 1
19
+ t.string "state"
20
+ t.datetime "created_at", null: false
21
+ t.datetime "updated_at", null: false
22
+ t.string "resource_type"
23
+ t.integer "resource_id"
24
+ end
25
+
26
+ add_index "vacancies", ["offeror_id"], name: "index_vacancies_on_offeror_id", using: :btree
27
+ add_index "vacancies", ["project_id", "name"], name: "index_vacancies_on_project_id_and_name", unique: true, using: :btree
28
+ add_index "vacancies", ["project_id"], name: "index_vacancies_on_project_id", using: :btree
29
+ add_index "vacancies", ["project_user_id"], name: "index_vacancies_on_project_user_id", using: :btree
30
+ add_index "vacancies", ["slug"], name: "index_vacancies_on_slug", unique: true, using: :btree
31
+ end
32
+
33
+ unless ActiveRecord::Base.connection.table_exists? 'candidatures'
34
+ create_table "candidatures", force: true do |t|
35
+ t.integer "vacancy_id"
36
+ t.integer "offeror_id"
37
+ t.string "name"
38
+ t.string "slug"
39
+ t.text "text"
40
+ t.string "state"
41
+ t.datetime "created_at", null: false
42
+ t.datetime "updated_at", null: false
43
+ t.string "resource_type"
44
+ t.integer "resource_id"
45
+ end
46
+
47
+ add_index "candidatures", ["resource_id", "resource_type", "vacancy_id"], name: "index_candidatures_on_resource_and_vacancy", unique: true, using: :btree
48
+ add_index "candidatures", ["slug"], name: "index_candidatures_on_slug", unique: true, using: :btree
49
+ add_index "candidatures", ["vacancy_id", "name"], name: "index_candidatures_on_vacancy_id_and_name", unique: true, using: :btree
50
+ add_index "candidatures", ["vacancy_id"], name: "index_candidatures_on_vacancy_id", using: :btree
51
+ end
52
+ end
53
+
54
+ def down
55
+ product.destroy if product = Product::Recruiting.first
56
+
57
+ drop_table :vacancies
58
+ drop_table :candidatures
59
+ end
60
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :voluntary_recruiting do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,13 @@
1
+ require 'voluntary'
2
+
3
+ require 'voluntary_recruiting/ability'
4
+ require 'voluntary_recruiting/navigation'
5
+ require 'voluntary_recruiting/concerns/model/user/recruitable'
6
+ require 'voluntary_recruiting/concerns/model/project/recruitable'
7
+ require 'voluntary_recruiting/concerns/model/project_user/recruitable'
8
+ require 'voluntary_recruiting/controller/project_owner_controller'
9
+
10
+ require 'voluntary_recruiting/engine'
11
+
12
+ module VoluntaryRecruiting
13
+ end
@@ -0,0 +1,17 @@
1
+ module VoluntaryRecruiting
2
+ class Ability
3
+ def self.after_initialize
4
+ Proc.new do |ability, user, options|
5
+ ability.can :read, [Vacancy, Candidature]
6
+
7
+ if user.present?
8
+ ability.can [:new, :create], [Vacancy, Candidature]
9
+ ability.can :restful_actions, Vacancy, offeror_id: user.id
10
+ ability.can Vacancy::EVENTS, Vacancy, offeror_id: user.id
11
+ ability.can Candidature::EVENTS, Candidature, offeror_id: user.id
12
+ ability.can :restful_actions, Candidature, resource_type: 'User', resource_id: user.id
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ module VoluntaryRecruiting
2
+ module Concerns
3
+ module Model
4
+ module Project
5
+ module Recruitable
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ has_many :vacancies, dependent: :destroy
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,19 @@
1
+ module VoluntaryRecruiting
2
+ module Concerns
3
+ module Model
4
+ module ProjectUser
5
+ module Recruitable
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ belongs_to :vacancy
10
+
11
+ validates :user_id, presence: true, uniqueness: { scope: [:project_id, :vacancy_id] }
12
+
13
+ attr_accessible :vacancy_id
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end